/*
 * This file exposes PyAST_Validate interface to check the integrity
 * of the given abstract syntax tree (potentially constructed manually).
 */
#include "Python.h"
#include "pycore_ast.h"           // asdl_stmt_seq
#include "pycore_pystate.h"       // _PyThreadState_GET()

#include <assert.h>
#include <stdbool.h>

struct validator {
    int recursion_depth;            /* current recursion depth */
    int recursion_limit;            /* recursion limit */
};

static int validate_stmts(struct validator *, asdl_stmt_seq *);
static int validate_exprs(struct validator *, asdl_expr_seq *, expr_context_ty, int);
static int validate_patterns(struct validator *, asdl_pattern_seq *, int);
static int validate_type_params(struct validator *, asdl_type_param_seq *);
static int _validate_nonempty_seq(asdl_seq *, const char *, const char *);
static int validate_stmt(struct validator *, stmt_ty);
static int validate_expr(struct validator *, expr_ty, expr_context_ty);
static int validate_pattern(struct validator *, pattern_ty, int);
static int validate_typeparam(struct validator *, type_param_ty);

#define VALIDATE_POSITIONS(node) \
    if (node->lineno > node->end_lineno) { \
        PyErr_Format(PyExc_ValueError, \
                     "AST node line range (%d, %d) is not valid", \
                     node->lineno, node->end_lineno); \
        return 0; \
    } \
    if ((node->lineno < 0 && node->end_lineno != node->lineno) || \
        (node->col_offset < 0 && node->col_offset != node->end_col_offset)) { \
        PyErr_Format(PyExc_ValueError, \
                     "AST node column range (%d, %d) for line range (%d, %d) is not valid", \
                     node->col_offset, node->end_col_offset, node->lineno, node->end_lineno); \
        return 0; \
    } \
    if (node->lineno == node->end_lineno && node->col_offset > node->end_col_offset) { \
        PyErr_Format(PyExc_ValueError, \
                     "line %d, column %d-%d is not a valid range", \
                     node->lineno, node->col_offset, node->end_col_offset); \
        return 0; \
    }

static int
validate_name(PyObject *name)
{
    assert(!PyErr_Occurred());
    assert(PyUnicode_Check(name));
    static const char * const forbidden[] = {
        "None",
        "True",
        "False",
        NULL
    };
    for (int i = 0; forbidden[i] != NULL; i++) {
        if (_PyUnicode_EqualToASCIIString(name, forbidden[i])) {
            PyErr_Format(PyExc_ValueError, "identifier field can't represent '%s' constant", forbidden[i]);
            return 0;
        }
    }
    return 1;
}

static int
validate_comprehension(struct validator *state, asdl_comprehension_seq *gens)
{
    assert(!PyErr_Occurred());
    if (!asdl_seq_LEN(gens)) {
        PyErr_SetString(PyExc_ValueError, "comprehension with no generators");
        return 0;
    }
    for (Py_ssize_t i = 0; i < asdl_seq_LEN(gens); i++) {
        comprehension_ty comp = asdl_seq_GET(gens, i);
        if (!validate_expr(state, comp->target, Store) ||
            !validate_expr(state, comp->iter, Load) ||
            !validate_exprs(state, comp->ifs, Load, 0))
            return 0;
    }
    return 1;
}

static int
validate_keywords(struct validator *state, asdl_keyword_seq *keywords)
{
    assert(!PyErr_Occurred());
    for (Py_ssize_t i = 0; i < asdl_seq_LEN(keywords); i++)
        if (!validate_expr(state, (asdl_seq_GET(keywords, i))->value, Load))
            return 0;
    return 1;
}

static int
validate_args(struct validator *state, asdl_arg_seq *args)
{
    assert(!PyErr_Occurred());
    for (Py_ssize_t i = 0; i < asdl_seq_LEN(args); i++) {
        arg_ty arg = asdl_seq_GET(args, i);
        VALIDATE_POSITIONS(arg);
        if (arg->annotation && !validate_expr(state, arg->annotation, Load))
            return 0;
    }
    return 1;
}

static const char *
expr_context_name(expr_context_ty ctx)
{
    switch (ctx) {
    case Load:
        return "Load";
    case Store:
        return "Store";
    case Del:
        return "Del";
    // No default case so compiler emits warning for unhandled cases
    }
    Py_UNREACHABLE();
}

static int
validate_arguments(struct validator *state, arguments_ty args)
{
    assert(!PyErr_Occurred());
    if (!validate_args(state, args->posonlyargs) || !validate_args(state, args->args)) {
        return 0;
    }
    if (args->vararg && args->vararg->annotation
        && !validate_expr(state, args->vararg->annotation, Load)) {
            return 0;
    }
    if (!validate_args(state, args->kwonlyargs))
        return 0;
    if (args->kwarg && args->kwarg->annotation
        && !validate_expr(state, args->kwarg->annotation, Load)) {
            return 0;
    }
    if (asdl_seq_LEN(args->defaults) > asdl_seq_LEN(args->posonlyargs) + asdl_seq_LEN(args->args)) {
        PyErr_SetString(PyExc_ValueError, "more positional defaults than args on arguments");
        return 0;
    }
    if (asdl_seq_LEN(args->kw_defaults) != asdl_seq_LEN(args->kwonlyargs)) {
        PyErr_SetString(PyExc_ValueError, "length of kwonlyargs is not the same as "
                        "kw_defaults on arguments");
        return 0;
    }
    return validate_exprs(state, args->defaults, Load, 0) && validate_exprs(state, args->kw_defaults, Load, 1);
}

static int
validate_constant(struct validator *state, PyObject *value)
{
    assert(!PyErr_Occurred());
    if (value == Py_None || value == Py_Ellipsis)
        return 1;

    if (PyLong_CheckExact(value)
            || PyFloat_CheckExact(value)
            || PyComplex_CheckExact(value)
            || PyBool_Check(value)
            || PyUnicode_CheckExact(value)
            || PyBytes_CheckExact(value))
        return 1;

    if (PyTuple_CheckExact(value) || PyFrozenSet_CheckExact(value)) {
        if (++state->recursion_depth > state->recursion_limit) {
            PyErr_SetString(PyExc_RecursionError,
                            "maximum recursion depth exceeded during compilation");
            return 0;
        }

        PyObject *it = PyObject_GetIter(value);
        if (it == NULL)
            return 0;

        while (1) {
            PyObject *item = PyIter_Next(it);
            if (item == NULL) {
                if (PyErr_Occurred()) {
                    Py_DECREF(it);
                    return 0;
                }
                break;
            }

            if (!validate_constant(state, item)) {
                Py_DECREF(it);
                Py_DECREF(item);
                return 0;
            }
            Py_DECREF(item);
        }

        Py_DECREF(it);
        --state->recursion_depth;
        return 1;
    }

    if (!PyErr_Occurred()) {
        PyErr_Format(PyExc_TypeError,
                     "got an invalid type in Constant: %s",
                     _PyType_Name(Py_TYPE(value)));
    }
    return 0;
}

static int
validate_expr(struct validator *state, expr_ty exp, expr_context_ty ctx)
{
    assert(!PyErr_Occurred());
    VALIDATE_POSITIONS(exp);
    int ret = -1;
    if (++state->recursion_depth > state->recursion_limit) {
        PyErr_SetString(PyExc_RecursionError,
                        "maximum recursion depth exceeded during compilation");
        return 0;
    }
    int check_ctx = 1;
    expr_context_ty actual_ctx;

    /* First check expression context. */
    switch (exp->kind) {
    case Attribute_kind:
        actual_ctx = exp->v.Attribute.ctx;
        break;
    case Subscript_kind:
        actual_ctx = exp->v.Subscript.ctx;
        break;
    case Starred_kind:
        actual_ctx = exp->v.Starred.ctx;
        break;
    case Name_kind:
        if (!validate_name(exp->v.Name.id)) {
            return 0;
        }
        actual_ctx = exp->v.Name.ctx;
        break;
    case List_kind:
        actual_ctx = exp->v.List.ctx;
        break;
    case Tuple_kind:
        actual_ctx = exp->v.Tuple.ctx;
        break;
    default:
        if (ctx != Load) {
            PyErr_Format(PyExc_ValueError, "expression which can't be "
                         "assigned to in %s context", expr_context_name(ctx));
            return 0;
        }
        check_ctx = 0;
        /* set actual_ctx to prevent gcc warning */
        actual_ctx = 0;
    }
    if (check_ctx && actual_ctx != ctx) {
        PyErr_Format(PyExc_ValueError, "expression must have %s context but has %s instead",
                     expr_context_name(ctx), expr_context_name(actual_ctx));
        return 0;
    }

    /* Now validate expression. */
    switch (exp->kind) {
    case BoolOp_kind:
        if (asdl_seq_LEN(exp->v.BoolOp.values) < 2) {
            PyErr_SetString(PyExc_ValueError, "BoolOp with less than 2 values");
            return 0;
        }
        ret = validate_exprs(state, exp->v.BoolOp.values, Load, 0);
        break;
    case BinOp_kind:
        ret = validate_expr(state, exp->v.BinOp.left, Load) &&
            validate_expr(state, exp->v.BinOp.right, Load);
        break;
    case UnaryOp_kind:
        ret = validate_expr(state, exp->v.UnaryOp.operand, Load);
        break;
    case Lambda_kind:
        ret = validate_arguments(state, exp->v.Lambda.args) &&
            validate_expr(state, exp->v.Lambda.body, Load);
        break;
    case IfExp_kind:
        ret = validate_expr(state, exp->v.IfExp.test, Load) &&
            validate_expr(state, exp->v.IfExp.body, Load) &&
            validate_expr(state, exp->v.IfExp.orelse, Load);
        break;
    case Dict_kind:
        if (asdl_seq_LEN(exp->v.Dict.keys) != asdl_seq_LEN(exp->v.Dict.values)) {
            PyErr_SetString(PyExc_ValueError,
                            "Dict doesn't have the same number of keys as values");
            return 0;
        }
        /* null_ok=1 for keys expressions to allow dict unpacking to work in
           dict literals, i.e. ``{**{a:b}}`` */
        ret = validate_exprs(state, exp->v.Dict.keys, Load, /*null_ok=*/ 1) &&
            validate_exprs(state, exp->v.Dict.values, Load, /*null_ok=*/ 0);
        break;
    case Set_kind:
        ret = validate_exprs(state, exp->v.Set.elts, Load, 0);
        break;
#define COMP(NAME) \
        case NAME ## _kind: \
            ret = validate_comprehension(state, exp->v.NAME.generators) && \
                validate_expr(state, exp->v.NAME.elt, Load); \
            break;
    COMP(ListComp)
    COMP(SetComp)
    COMP(GeneratorExp)
#undef COMP
    case DictComp_kind:
        ret = validate_comprehension(state, exp->v.DictComp.generators) &&
            validate_expr(state, exp->v.DictComp.key, Load) &&
            validate_expr(state, exp->v.DictComp.value, Load);
        break;
    case Yield_kind:
        ret = !exp->v.Yield.value || validate_expr(state, exp->v.Yield.value, Load);
        break;
    case YieldFrom_kind:
        ret = validate_expr(state, exp->v.YieldFrom.value, Load);
        break;
    case Await_kind:
        ret = validate_expr(state, exp->v.Await.value, Load);
        break;
    case Compare_kind:
        if (!asdl_seq_LEN(exp->v.Compare.comparators)) {
            PyErr_SetString(PyExc_ValueError, "Compare with no comparators");
            return 0;
        }
        if (asdl_seq_LEN(exp->v.Compare.comparators) !=
            asdl_seq_LEN(exp->v.Compare.ops)) {
            PyErr_SetString(PyExc_ValueError, "Compare has a different number "
                            "of comparators and operands");
            return 0;
        }
        ret = validate_exprs(state, exp->v.Compare.comparators, Load, 0) &&
            validate_expr(state, exp->v.Compare.left, Load);
        break;
    case Call_kind:
        ret = validate_expr(state, exp->v.Call.func, Load) &&
            validate_exprs(state, exp->v.Call.args, Load, 0) &&
            validate_keywords(state, exp->v.Call.keywords);
        break;
    case Constant_kind:
        if (!validate_constant(state, exp->v.Constant.value)) {
            return 0;
        }
        ret = 1;
        break;
    case JoinedStr_kind:
        ret = validate_exprs(state, exp->v.JoinedStr.values, Load, 0);
        break;
    case FormattedValue_kind:
        if (validate_expr(state, exp->v.FormattedValue.value, Load) == 0)
            return 0;
        if (exp->v.FormattedValue.format_spec) {
            ret = validate_expr(state, exp->v.FormattedValue.format_spec, Load);
            break;
        }
        ret = 1;
        break;
    case Attribute_kind:
        ret = validate_expr(state, exp->v.Attribute.value, Load);
        break;
    case Subscript_kind:
        ret = validate_expr(state, exp->v.Subscript.slice, Load) &&
            validate_expr(state, exp->v.Subscript.value, Load);
        break;
    case Starred_kind:
        ret = validate_expr(state, exp->v.Starred.value, ctx);
        break;
    case Slice_kind:
        ret = (!exp->v.Slice.lower || validate_expr(state, exp->v.Slice.lower, Load)) &&
            (!exp->v.Slice.upper || validate_expr(state, exp->v.Slice.upper, Load)) &&
            (!exp->v.Slice.step || validate_expr(state, exp->v.Slice.step, Load));
        break;
    case List_kind:
        ret = validate_exprs(state, exp->v.List.elts, ctx, 0);
        break;
    case Tuple_kind:
        ret = validate_exprs(state, exp->v.Tuple.elts, ctx, 0);
        break;
    case NamedExpr_kind:
        if (exp->v.NamedExpr.target->kind != Name_kind) {
            PyErr_SetString(PyExc_TypeError,
                            "NamedExpr target must be a Name");
            return 0;
        }
        ret = validate_expr(state, exp->v.NamedExpr.value, Load);
        break;
    /* This last case doesn't have any checking. */
    case Name_kind:
        ret = 1;
        break;
    // No default case so compiler emits warning for unhandled cases
    }
    if (ret < 0) {
        PyErr_SetString(PyExc_SystemError, "unexpected expression");
        ret = 0;
    }
    state->recursion_depth--;
    return ret;
}


// Note: the ensure_literal_* functions are only used to validate a restricted
//       set of non-recursive literals that have already been checked with
//       validate_expr, so they don't accept the validator state
static int
ensure_literal_number(expr_ty exp, bool allow_real, bool allow_imaginary)
{
    assert(exp->kind == Constant_kind);
    PyObject *value = exp->v.Constant.value;
    return (allow_real && PyFloat_CheckExact(value)) ||
           (allow_real && PyLong_CheckExact(value)) ||
           (allow_imaginary && PyComplex_CheckExact(value));
}

static int
ensure_literal_negative(expr_ty exp, bool allow_real, bool allow_imaginary)
{
    assert(exp->kind == UnaryOp_kind);
    // Must be negation ...
    if (exp->v.UnaryOp.op != USub) {
        return 0;
    }
    // ... of a constant ...
    expr_ty operand = exp->v.UnaryOp.operand;
    if (operand->kind != Constant_kind) {
        return 0;
    }
    // ... number
    return ensure_literal_number(operand, allow_real, allow_imaginary);
}

static int
ensure_literal_complex(expr_ty exp)
{
    assert(exp->kind == BinOp_kind);
    expr_ty left = exp->v.BinOp.left;
    expr_ty right = exp->v.BinOp.right;
    // Ensure op is addition or subtraction
    if (exp->v.BinOp.op != Add && exp->v.BinOp.op != Sub) {
        return 0;
    }
    // Check LHS is a real number (potentially signed)
    switch (left->kind)
    {
        case Constant_kind:
            if (!ensure_literal_number(left, /*real=*/true, /*imaginary=*/false)) {
                return 0;
            }
            break;
        case UnaryOp_kind:
            if (!ensure_literal_negative(left, /*real=*/true, /*imaginary=*/false)) {
                return 0;
            }
            break;
        default:
            return 0;
    }
    // Check RHS is an imaginary number (no separate sign allowed)
    switch (right->kind)
    {
        case Constant_kind:
            if (!ensure_literal_number(right, /*real=*/false, /*imaginary=*/true)) {
                return 0;
            }
            break;
        default:
            return 0;
    }
    return 1;
}

static int
validate_pattern_match_value(struct validator *state, expr_ty exp)
{
    assert(!PyErr_Occurred());
    if (!validate_expr(state, exp, Load)) {
        return 0;
    }

    switch (exp->kind)
    {
        case Constant_kind:
            /* Ellipsis and immutable sequences are not allowed.
               For True, False and None, MatchSingleton() should
               be used */
            if (!validate_expr(state, exp, Load)) {
                return 0;
            }
            PyObject *literal = exp->v.Constant.value;
            if (PyLong_CheckExact(literal) || PyFloat_CheckExact(literal) ||
                PyBytes_CheckExact(literal) || PyComplex_CheckExact(literal) ||
                PyUnicode_CheckExact(literal)) {
                return 1;
            }
            PyErr_SetString(PyExc_ValueError,
                            "unexpected constant inside of a literal pattern");
            return 0;
        case Attribute_kind:
            // Constants and attribute lookups are always permitted
            return 1;
        case UnaryOp_kind:
            // Negated numbers are permitted (whether real or imaginary)
            // Compiler will complain if AST folding doesn't create a constant
            if (ensure_literal_negative(exp, /*real=*/true, /*imaginary=*/true)) {
                return 1;
            }
            break;
        case BinOp_kind:
            // Complex literals are permitted
            // Compiler will complain if AST folding doesn't create a constant
            if (ensure_literal_complex(exp)) {
                return 1;
            }
            break;
        case JoinedStr_kind:
            // Handled in the later stages
            return 1;
        default:
            break;
    }
    PyErr_SetString(PyExc_ValueError,
                    "patterns may only match literals and attribute lookups");
    return 0;
}

static int
validate_capture(PyObject *name)
{
    assert(!PyErr_Occurred());
    if (_PyUnicode_EqualToASCIIString(name, "_")) {
        PyErr_Format(PyExc_ValueError, "can't capture name '_' in patterns");
        return 0;
    }
    return validate_name(name);
}

static int
validate_pattern(struct validator *state, pattern_ty p, int star_ok)
{
    assert(!PyErr_Occurred());
    VALIDATE_POSITIONS(p);
    int ret = -1;
    if (++state->recursion_depth > state->recursion_limit) {
        PyErr_SetString(PyExc_RecursionError,
                        "maximum recursion depth exceeded during compilation");
        return 0;
    }
    switch (p->kind) {
        case MatchValue_kind:
            ret = validate_pattern_match_value(state, p->v.MatchValue.value);
            break;
        case MatchSingleton_kind:
            ret = p->v.MatchSingleton.value == Py_None || PyBool_Check(p->v.MatchSingleton.value);
            if (!ret) {
                PyErr_SetString(PyExc_ValueError,
                                "MatchSingleton can only contain True, False and None");
            }
            break;
        case MatchSequence_kind:
            ret = validate_patterns(state, p->v.MatchSequence.patterns, /*star_ok=*/1);
            break;
        case MatchMapping_kind:
            if (asdl_seq_LEN(p->v.MatchMapping.keys) != asdl_seq_LEN(p->v.MatchMapping.patterns)) {
                PyErr_SetString(PyExc_ValueError,
                                "MatchMapping doesn't have the same number of keys as patterns");
                ret = 0;
                break;
            }

            if (p->v.MatchMapping.rest && !validate_capture(p->v.MatchMapping.rest)) {
                ret = 0;
                break;
            }

            asdl_expr_seq *keys = p->v.MatchMapping.keys;
            for (Py_ssize_t i = 0; i < asdl_seq_LEN(keys); i++) {
                expr_ty key = asdl_seq_GET(keys, i);
                if (key->kind == Constant_kind) {
                    PyObject *literal = key->v.Constant.value;
                    if (literal == Py_None || PyBool_Check(literal)) {
                        /* validate_pattern_match_value will ensure the key
                           doesn't contain True, False and None but it is
                           syntactically valid, so we will pass those on in
                           a special case. */
                        continue;
                    }
                }
                if (!validate_pattern_match_value(state, key)) {
                    ret = 0;
                    break;
                }
            }
            if (ret == 0) {
                break;
            }
            ret = validate_patterns(state, p->v.MatchMapping.patterns, /*star_ok=*/0);
            break;
        case MatchClass_kind:
            if (asdl_seq_LEN(p->v.MatchClass.kwd_attrs) != asdl_seq_LEN(p->v.MatchClass.kwd_patterns)) {
                PyErr_SetString(PyExc_ValueError,
                                "MatchClass doesn't have the same number of keyword attributes as patterns");
                ret = 0;
                break;
            }
            if (!validate_expr(state, p->v.MatchClass.cls, Load)) {
                ret = 0;
                break;
            }

            expr_ty cls = p->v.MatchClass.cls;
            while (1) {
                if (cls->kind == Name_kind) {
                    break;
                }
                else if (cls->kind == Attribute_kind) {
                    cls = cls->v.Attribute.value;
                    continue;
                }
                else {
                    PyErr_SetString(PyExc_ValueError,
                                    "MatchClass cls field can only contain Name or Attribute nodes.");
                    ret = 0;
                    break;
                }
            }
            if (ret == 0) {
                break;
            }

            for (Py_ssize_t i = 0; i < asdl_seq_LEN(p->v.MatchClass.kwd_attrs); i++) {
                PyObject *identifier = asdl_seq_GET(p->v.MatchClass.kwd_attrs, i);
                if (!validate_name(identifier)) {
                    ret = 0;
                    break;
                }
            }
            if (ret == 0) {
                break;
            }

            if (!validate_patterns(state, p->v.MatchClass.patterns, /*star_ok=*/0)) {
                ret = 0;
                break;
            }

            ret = validate_patterns(state, p->v.MatchClass.kwd_patterns, /*star_ok=*/0);
            break;
        case MatchStar_kind:
            if (!star_ok) {
                PyErr_SetString(PyExc_ValueError, "can't use MatchStar here");
                ret = 0;
                break;
            }
            ret = p->v.MatchStar.name == NULL || validate_capture(p->v.MatchStar.name);
            break;
        case MatchAs_kind:
            if (p->v.MatchAs.name && !validate_capture(p->v.MatchAs.name)) {
                ret = 0;
                break;
            }
            if (p->v.MatchAs.pattern == NULL) {
                ret = 1;
            }
            else if (p->v.MatchAs.name == NULL) {
                PyErr_SetString(PyExc_ValueError,
                                "MatchAs must specify a target name if a pattern is given");
                ret = 0;
            }
            else {
                ret = validate_pattern(state, p->v.MatchAs.pattern, /*star_ok=*/0);
            }
            break;
        case MatchOr_kind:
            if (asdl_seq_LEN(p->v.MatchOr.patterns) < 2) {
                PyErr_SetString(PyExc_ValueError,
                                "MatchOr requires at least 2 patterns");
                ret = 0;
                break;
            }
            ret = validate_patterns(state, p->v.MatchOr.patterns, /*star_ok=*/0);
            break;
    // No default case, so the compiler will emit a warning if new pattern
    // kinds are added without being handled here
    }
    if (ret < 0) {
        PyErr_SetString(PyExc_SystemError, "unexpected pattern");
        ret = 0;
    }
    state->recursion_depth--;
    return ret;
}

static int
_validate_nonempty_seq(asdl_seq *seq, const char *what, const char *owner)
{
    if (asdl_seq_LEN(seq))
        return 1;
    PyErr_Format(PyExc_ValueError, "empty %s on %s", what, owner);
    return 0;
}
#define validate_nonempty_seq(seq, what, owner) _validate_nonempty_seq((asdl_seq*)seq, what, owner)

static int
validate_assignlist(struct validator *state, asdl_expr_seq *targets, expr_context_ty ctx)
{
    assert(!PyErr_Occurred());
    return validate_nonempty_seq(targets, "targets", ctx == Del ? "Delete" : "Assign") &&
        validate_exprs(state, targets, ctx, 0);
}

static int
validate_body(struct validator *state, asdl_stmt_seq *body, const char *owner)
{
    assert(!PyErr_Occurred());
    return validate_nonempty_seq(body, "body", owner) && validate_stmts(state, body);
}

static int
validate_stmt(struct validator *state, stmt_ty stmt)
{
    assert(!PyErr_Occurred());
    VALIDATE_POSITIONS(stmt);
    int ret = -1;
    if (++state->recursion_depth > state->recursion_limit) {
        PyErr_SetString(PyExc_RecursionError,
                        "maximum recursion depth exceeded during compilation");
        return 0;
    }
    switch (stmt->kind) {
    case FunctionDef_kind:
        ret = validate_body(state, stmt->v.FunctionDef.body, "FunctionDef") &&
            validate_type_params(state, stmt->v.FunctionDef.type_params) &&
            validate_arguments(state, stmt->v.FunctionDef.args) &&
            validate_exprs(state, stmt->v.FunctionDef.decorator_list, Load, 0) &&
            (!stmt->v.FunctionDef.returns ||
             validate_expr(state, stmt->v.FunctionDef.returns, Load));
        break;
    case ClassDef_kind:
        ret = validate_body(state, stmt->v.ClassDef.body, "ClassDef") &&
            validate_type_params(state, stmt->v.ClassDef.type_params) &&
            validate_exprs(state, stmt->v.ClassDef.bases, Load, 0) &&
            validate_keywords(state, stmt->v.ClassDef.keywords) &&
            validate_exprs(state, stmt->v.ClassDef.decorator_list, Load, 0);
        break;
    case Return_kind:
        ret = !stmt->v.Return.value || validate_expr(state, stmt->v.Return.value, Load);
        break;
    case Delete_kind:
        ret = validate_assignlist(state, stmt->v.Delete.targets, Del);
        break;
    case Assign_kind:
        ret = validate_assignlist(state, stmt->v.Assign.targets, Store) &&
            validate_expr(state, stmt->v.Assign.value, Load);
        break;
    case AugAssign_kind:
        ret = validate_expr(state, stmt->v.AugAssign.target, Store) &&
            validate_expr(state, stmt->v.AugAssign.value, Load);
        break;
    case AnnAssign_kind:
        if (stmt->v.AnnAssign.target->kind != Name_kind &&
            stmt->v.AnnAssign.simple) {
            PyErr_SetString(PyExc_TypeError,
                            "AnnAssign with simple non-Name target");
            return 0;
        }
        ret = validate_expr(state, stmt->v.AnnAssign.target, Store) &&
               (!stmt->v.AnnAssign.value ||
                validate_expr(state, stmt->v.AnnAssign.value, Load)) &&
               validate_expr(state, stmt->v.AnnAssign.annotation, Load);
        break;
    case TypeAlias_kind:
        if (stmt->v.TypeAlias.name->kind != Name_kind) {
            PyErr_SetString(PyExc_TypeError,
                            "TypeAlias with non-Name name");
            return 0;
        }
        ret = validate_expr(state, stmt->v.TypeAlias.name, Store) &&
            validate_type_params(state, stmt->v.TypeAlias.type_params) &&
            validate_expr(state, stmt->v.TypeAlias.value, Load);
        break;
    case For_kind:
        ret = validate_expr(state, stmt->v.For.target, Store) &&
            validate_expr(state, stmt->v.For.iter, Load) &&
            validate_body(state, stmt->v.For.body, "For") &&
            validate_stmts(state, stmt->v.For.orelse);
        break;
    case AsyncFor_kind:
        ret = validate_expr(state, stmt->v.AsyncFor.target, Store) &&
            validate_expr(state, stmt->v.AsyncFor.iter, Load) &&
            validate_body(state, stmt->v.AsyncFor.body, "AsyncFor") &&
            validate_stmts(state, stmt->v.AsyncFor.orelse);
        break;
    case While_kind:
        ret = validate_expr(state, stmt->v.While.test, Load) &&
            validate_body(state, stmt->v.While.body, "While") &&
            validate_stmts(state, stmt->v.While.orelse);
        break;
    case If_kind:
        ret = validate_expr(state, stmt->v.If.test, Load) &&
            validate_body(state, stmt->v.If.body, "If") &&
            validate_stmts(state, stmt->v.If.orelse);
        break;
    case With_kind:
        if (!validate_nonempty_seq(stmt->v.With.items, "items", "With"))
            return 0;
        for (Py_ssize_t i = 0; i < asdl_seq_LEN(stmt->v.With.items); i++) {
            withitem_ty item = asdl_seq_GET(stmt->v.With.items, i);
            if (!validate_expr(state, item->context_expr, Load) ||
                (item->optional_vars && !validate_expr(state, item->optional_vars, Store)))
                return 0;
        }
        ret = validate_body(state, stmt->v.With.body, "With");
        break;
    case AsyncWith_kind:
        if (!validate_nonempty_seq(stmt->v.AsyncWith.items, "items", "AsyncWith"))
            return 0;
        for (Py_ssize_t i = 0; i < asdl_seq_LEN(stmt->v.AsyncWith.items); i++) {
            withitem_ty item = asdl_seq_GET(stmt->v.AsyncWith.items, i);
            if (!validate_expr(state, item->context_expr, Load) ||
                (item->optional_vars && !validate_expr(state, item->optional_vars, Store)))
                return 0;
        }
        ret = validate_body(state, stmt->v.AsyncWith.body, "AsyncWith");
        break;
    case Match_kind:
        if (!validate_expr(state, stmt->v.Match.subject, Load)
            || !validate_nonempty_seq(stmt->v.Match.cases, "cases", "Match")) {
            return 0;
        }
        for (Py_ssize_t i = 0; i < asdl_seq_LEN(stmt->v.Match.cases); i++) {
            match_case_ty m = asdl_seq_GET(stmt->v.Match.cases, i);
            if (!validate_pattern(state, m->pattern, /*star_ok=*/0)
                || (m->guard && !validate_expr(state, m->guard, Load))
                || !validate_body(state, m->body, "match_case")) {
                return 0;
            }
        }
        ret = 1;
        break;
    case Raise_kind:
        if (stmt->v.Raise.exc) {
            ret = validate_expr(state, stmt->v.Raise.exc, Load) &&
                (!stmt->v.Raise.cause || validate_expr(state, stmt->v.Raise.cause, Load));
            break;
        }
        if (stmt->v.Raise.cause) {
            PyErr_SetString(PyExc_ValueError, "Raise with cause but no exception");
            return 0;
        }
        ret = 1;
        break;
    case Try_kind:
        if (!validate_body(state, stmt->v.Try.body, "Try"))
            return 0;
        if (!asdl_seq_LEN(stmt->v.Try.handlers) &&
            !asdl_seq_LEN(stmt->v.Try.finalbody)) {
            PyErr_SetString(PyExc_ValueError, "Try has neither except handlers nor finalbody");
            return 0;
        }
        if (!asdl_seq_LEN(stmt->v.Try.handlers) &&
            asdl_seq_LEN(stmt->v.Try.orelse)) {
            PyErr_SetString(PyExc_ValueError, "Try has orelse but no except handlers");
            return 0;
        }
        for (Py_ssize_t i = 0; i < asdl_seq_LEN(stmt->v.Try.handlers); i++) {
            excepthandler_ty handler = asdl_seq_GET(stmt->v.Try.handlers, i);
            VALIDATE_POSITIONS(handler);
            if ((handler->v.ExceptHandler.type &&
                 !validate_expr(state, handler->v.ExceptHandler.type, Load)) ||
                !validate_body(state, handler->v.ExceptHandler.body, "ExceptHandler"))
                return 0;
        }
        ret = (!asdl_seq_LEN(stmt->v.Try.finalbody) ||
                validate_stmts(state, stmt->v.Try.finalbody)) &&
            (!asdl_seq_LEN(stmt->v.Try.orelse) ||
             validate_stmts(state, stmt->v.Try.orelse));
        break;
    case TryStar_kind:
        if (!validate_body(state, stmt->v.TryStar.body, "TryStar"))
            return 0;
        if (!asdl_seq_LEN(stmt->v.TryStar.handlers) &&
            !asdl_seq_LEN(stmt->v.TryStar.finalbody)) {
            PyErr_SetString(PyExc_ValueError, "TryStar has neither except handlers nor finalbody");
            return 0;
        }
        if (!asdl_seq_LEN(stmt->v.TryStar.handlers) &&
            asdl_seq_LEN(stmt->v.TryStar.orelse)) {
            PyErr_SetString(PyExc_ValueError, "TryStar has orelse but no except handlers");
            return 0;
        }
        for (Py_ssize_t i = 0; i < asdl_seq_LEN(stmt->v.TryStar.handlers); i++) {
            excepthandler_ty handler = asdl_seq_GET(stmt->v.TryStar.handlers, i);
            if ((handler->v.ExceptHandler.type &&
                 !validate_expr(state, handler->v.ExceptHandler.type, Load)) ||
                !validate_body(state, handler->v.ExceptHandler.body, "ExceptHandler"))
                return 0;
        }
        ret = (!asdl_seq_LEN(stmt->v.TryStar.finalbody) ||
                validate_stmts(state, stmt->v.TryStar.finalbody)) &&
            (!asdl_seq_LEN(stmt->v.TryStar.orelse) ||
             validate_stmts(state, stmt->v.TryStar.orelse));
        break;
    case Assert_kind:
        ret = validate_expr(state, stmt->v.Assert.test, Load) &&
            (!stmt->v.Assert.msg || validate_expr(state, stmt->v.Assert.msg, Load));
        break;
    case Import_kind:
        ret = validate_nonempty_seq(stmt->v.Import.names, "names", "Import");
        break;
    case ImportFrom_kind:
        if (stmt->v.ImportFrom.level < 0) {
            PyErr_SetString(PyExc_ValueError, "Negative ImportFrom level");
            return 0;
        }
        ret = validate_nonempty_seq(stmt->v.ImportFrom.names, "names", "ImportFrom");
        break;
    case Global_kind:
        ret = validate_nonempty_seq(stmt->v.Global.names, "names", "Global");
        break;
    case Nonlocal_kind:
        ret = validate_nonempty_seq(stmt->v.Nonlocal.names, "names", "Nonlocal");
        break;
    case Expr_kind:
        ret = validate_expr(state, stmt->v.Expr.value, Load);
        break;
    case AsyncFunctionDef_kind:
        ret = validate_body(state, stmt->v.AsyncFunctionDef.body, "AsyncFunctionDef") &&
            validate_type_params(state, stmt->v.AsyncFunctionDef.type_params) &&
            validate_arguments(state, stmt->v.AsyncFunctionDef.args) &&
            validate_exprs(state, stmt->v.AsyncFunctionDef.decorator_list, Load, 0) &&
            (!stmt->v.AsyncFunctionDef.returns ||
             validate_expr(state, stmt->v.AsyncFunctionDef.returns, Load));
        break;
    case Pass_kind:
    case Break_kind:
    case Continue_kind:
        ret = 1;
        break;
    // No default case so compiler emits warning for unhandled cases
    }
    if (ret < 0) {
        PyErr_SetString(PyExc_SystemError, "unexpected statement");
        ret = 0;
    }
    state->recursion_depth--;
    return ret;
}

static int
validate_stmts(struct validator *state, asdl_stmt_seq *seq)
{
    assert(!PyErr_Occurred());
    for (Py_ssize_t i = 0; i < asdl_seq_LEN(seq); i++) {
        stmt_ty stmt = asdl_seq_GET(seq, i);
        if (stmt) {
            if (!validate_stmt(state, stmt))
                return 0;
        }
        else {
            PyErr_SetString(PyExc_ValueError,
                            "None disallowed in statement list");
            return 0;
        }
    }
    return 1;
}

static int
validate_exprs(struct validator *state, asdl_expr_seq *exprs, expr_context_ty ctx, int null_ok)
{
    assert(!PyErr_Occurred());
    for (Py_ssize_t i = 0; i < asdl_seq_LEN(exprs); i++) {
        expr_ty expr = asdl_seq_GET(exprs, i);
        if (expr) {
            if (!validate_expr(state, expr, ctx))
                return 0;
        }
        else if (!null_ok) {
            PyErr_SetString(PyExc_ValueError,
                            "None disallowed in expression list");
            return 0;
        }

    }
    return 1;
}

static int
validate_patterns(struct validator *state, asdl_pattern_seq *patterns, int star_ok)
{
    assert(!PyErr_Occurred());
    for (Py_ssize_t i = 0; i < asdl_seq_LEN(patterns); i++) {
        pattern_ty pattern = asdl_seq_GET(patterns, i);
        if (!validate_pattern(state, pattern, star_ok)) {
            return 0;
        }
    }
    return 1;
}

static int
validate_typeparam(struct validator *state, type_param_ty tp)
{
    VALIDATE_POSITIONS(tp);
    int ret = -1;
    switch (tp->kind) {
        case TypeVar_kind:
            ret = validate_name(tp->v.TypeVar.name) &&
                (!tp->v.TypeVar.bound ||
                 validate_expr(state, tp->v.TypeVar.bound, Load));
            break;
        case ParamSpec_kind:
            ret = validate_name(tp->v.ParamSpec.name);
            break;
        case TypeVarTuple_kind:
            ret = validate_name(tp->v.TypeVarTuple.name);
            break;
    }
    return ret;
}

static int
validate_type_params(struct validator *state, asdl_type_param_seq *tps)
{
    Py_ssize_t i;
    for (i = 0; i < asdl_seq_LEN(tps); i++) {
        type_param_ty tp = asdl_seq_GET(tps, i);
        if (tp) {
            if (!validate_typeparam(state, tp))
                return 0;
        }
    }
    return 1;
}

int
_PyAST_Validate(mod_ty mod)
{
    assert(!PyErr_Occurred());
    int res = -1;
    struct validator state;
    PyThreadState *tstate;
    int starting_recursion_depth;

    /* Setup recursion depth check counters */
    tstate = _PyThreadState_GET();
    if (!tstate) {
        return 0;
    }
    /* Be careful here to prevent overflow. */
    int recursion_depth = Py_C_RECURSION_LIMIT - tstate->c_recursion_remaining;
    starting_recursion_depth = recursion_depth;
    state.recursion_depth = starting_recursion_depth;
    state.recursion_limit = Py_C_RECURSION_LIMIT;

    switch (mod->kind) {
    case Module_kind:
        res = validate_stmts(&state, mod->v.Module.body);
        break;
    case Interactive_kind:
        res = validate_stmts(&state, mod->v.Interactive.body);
        break;
    case Expression_kind:
        res = validate_expr(&state, mod->v.Expression.body, Load);
        break;
    case FunctionType_kind:
        res = validate_exprs(&state, mod->v.FunctionType.argtypes, Load, /*null_ok=*/0) &&
              validate_expr(&state, mod->v.FunctionType.returns, Load);
        break;
    // No default case so compiler emits warning for unhandled cases
    }

    if (res < 0) {
        PyErr_SetString(PyExc_SystemError, "impossible module node");
        return 0;
    }

    /* Check that the recursion depth counting balanced correctly */
    if (res && state.recursion_depth != starting_recursion_depth) {
        PyErr_Format(PyExc_SystemError,
            "AST validator recursion depth mismatch (before=%d, after=%d)",
            starting_recursion_depth, state.recursion_depth);
        return 0;
    }
    return res;
}

PyObject *
_PyAST_GetDocString(asdl_stmt_seq *body)
{
    if (!asdl_seq_LEN(body)) {
        return NULL;
    }
    stmt_ty st = asdl_seq_GET(body, 0);
    if (st->kind != Expr_kind) {
        return NULL;
    }
    expr_ty e = st->v.Expr.value;
    if (e->kind == Constant_kind && PyUnicode_CheckExact(e->v.Constant.value)) {
        return e->v.Constant.value;
    }
    return NULL;
}
