/*----------------------------------------------------------------------------*/
/* This file is generated by the templates/template.rb script and should not  */
/* be modified manually.                                                      */
/* To change the template see                                                 */
/* templates/ext/rbs_extension/ast_translation.c.erb                          */
/*----------------------------------------------------------------------------*/

#include "ast_translation.h"

#include "class_constants.h"
#include "rbs_string_bridging.h"
#include "legacy_location.h"

VALUE EMPTY_ARRAY;
VALUE EMPTY_HASH;

#define RBS_LOCATION_CHILDREN_SIZE(cap) (sizeof(rbs_location_children) + sizeof(rbs_location_entry) * ((cap) - 1))
#define RBS_LOCATION_REQUIRED_P(loc, i) ((loc)->children->required_p & (1 << (i)))
#define RBS_LOCATION_OPTIONAL_P(loc, i) (!RBS_LOCATION_REQUIRED_P((loc), (i)))

rbs_translation_context_t rbs_translation_context_create(rbs_constant_pool_t *constant_pool, VALUE buffer, rb_encoding *ruby_encoding) {
    return (rbs_translation_context_t) {
        .constant_pool = constant_pool,
        .buffer = buffer,
        .encoding = ruby_encoding,
        .reusable_kwargs_hash = rb_hash_new(),
    };
}

VALUE rbs_node_list_to_ruby_array(rbs_translation_context_t ctx, rbs_node_list_t *list) {
    VALUE ruby_array = rb_ary_new();

    for (rbs_node_list_node_t *n = list->head; n != NULL; n = n->next) {
        rb_ary_push(ruby_array, rbs_struct_to_ruby_value(ctx, n->node));
    }

    return ruby_array;
}

VALUE rbs_hash_to_ruby_hash(rbs_translation_context_t ctx, rbs_hash_t *rbs_hash) {
    if (!rbs_hash->head) {
        return EMPTY_HASH;
    }

    VALUE ruby_hash = rb_hash_new();

    for (rbs_hash_node_t *n = rbs_hash->head; n != NULL; n = n->next) {
        VALUE key = rbs_struct_to_ruby_value(ctx, n->key);
        VALUE value = rbs_struct_to_ruby_value(ctx, n->value);
        rb_hash_aset(ruby_hash, key, value);
    }

    return ruby_hash;
}

VALUE rbs_location_range_to_ruby_location(rbs_translation_context_t ctx, rbs_location_range range) {
    if (RBS_LOCATION_NULL_RANGE_P(range)) {
        return Qnil;
    }

    return rbs_new_location2(ctx.buffer, range.start_char, range.end_char);
}

VALUE rbs_location_range_list_to_ruby_array(rbs_translation_context_t ctx, rbs_location_range_list_t *list) {
    if (list == NULL) {
        return EMPTY_ARRAY;
    }

    VALUE ruby_array = rb_ary_new();

    for (rbs_location_range_list_node_t *n = list->head; n != NULL; n = n->next) {
        rb_ary_push(ruby_array, rbs_location_range_to_ruby_location(ctx, n->range));
    }

    return ruby_array;
}

VALUE rbs_attr_ivar_name_to_ruby(rbs_translation_context_t ctx, rbs_attr_ivar_name_t ivar_name) {
    switch (ivar_name.tag) {
    case RBS_ATTR_IVAR_NAME_TAG_NAME: {
        rbs_constant_t *constant = rbs_constant_pool_id_to_constant(ctx.constant_pool, ivar_name.name);
        assert(constant != NULL && "constant is NULL");
        assert(constant->start != NULL && "constant->start is NULL");

        return ID2SYM(rb_intern3((const char *) constant->start, constant->length, ctx.encoding));
    }
    case RBS_ATTR_IVAR_NAME_TAG_UNSPECIFIED:
        return Qnil;
    case RBS_ATTR_IVAR_NAME_TAG_EMPTY:
        return Qfalse;
    default:
        rb_fatal("unknown enum rbs_attr_ivar_name_tag ivar_name.tag: %d", ivar_name.tag);
    }
}

VALUE rbs_attribute_visibility_to_ruby(enum rbs_attribute_visibility value) {
    switch (value) {
    case RBS_ATTRIBUTE_VISIBILITY_UNSPECIFIED:
        return Qnil;
    case RBS_ATTRIBUTE_VISIBILITY_PUBLIC:
        return rb_id2sym(rb_intern("public"));
    case RBS_ATTRIBUTE_VISIBILITY_PRIVATE:
        return rb_id2sym(rb_intern("private"));
    default:
        rb_fatal("unknown enum rbs_attribute_visibility value: %d", value);
    }
}

VALUE rbs_attribute_kind_to_ruby(enum rbs_attribute_kind value) {
    switch (value) {
    case RBS_ATTRIBUTE_KIND_INSTANCE:
        return rb_id2sym(rb_intern("instance"));
    case RBS_ATTRIBUTE_KIND_SINGLETON:
        return rb_id2sym(rb_intern("singleton"));
    default:
        rb_fatal("unknown enum rbs_attribute_kind value: %d", value);
    }
}

VALUE rbs_alias_kind_to_ruby(enum rbs_alias_kind value) {
    switch (value) {
    case RBS_ALIAS_KIND_INSTANCE:
        return rb_id2sym(rb_intern("instance"));
    case RBS_ALIAS_KIND_SINGLETON:
        return rb_id2sym(rb_intern("singleton"));
    default:
        rb_fatal("unknown enum rbs_alias_kind value: %d", value);
    }
}

VALUE rbs_method_definition_kind_to_ruby(enum rbs_method_definition_kind value) {
    switch (value) {
    case RBS_METHOD_DEFINITION_KIND_INSTANCE:
        return rb_id2sym(rb_intern("instance"));
    case RBS_METHOD_DEFINITION_KIND_SINGLETON:
        return rb_id2sym(rb_intern("singleton"));
    case RBS_METHOD_DEFINITION_KIND_SINGLETON_INSTANCE:
        return rb_id2sym(rb_intern("singleton_instance"));
    default:
        rb_fatal("unknown enum rbs_method_definition_kind value: %d", value);
    }
}

VALUE rbs_method_definition_visibility_to_ruby(enum rbs_method_definition_visibility value) {
    switch (value) {
    case RBS_METHOD_DEFINITION_VISIBILITY_UNSPECIFIED:
        return Qnil;
    case RBS_METHOD_DEFINITION_VISIBILITY_PUBLIC:
        return rb_id2sym(rb_intern("public"));
    case RBS_METHOD_DEFINITION_VISIBILITY_PRIVATE:
        return rb_id2sym(rb_intern("private"));
    default:
        rb_fatal("unknown enum rbs_method_definition_visibility value: %d", value);
    }
}

VALUE rbs_type_param_variance_to_ruby(enum rbs_type_param_variance value) {
    switch (value) {
    case RBS_TYPE_PARAM_VARIANCE_INVARIANT:
        return rb_id2sym(rb_intern("invariant"));
    case RBS_TYPE_PARAM_VARIANCE_COVARIANT:
        return rb_id2sym(rb_intern("covariant"));
    case RBS_TYPE_PARAM_VARIANCE_CONTRAVARIANT:
        return rb_id2sym(rb_intern("contravariant"));
    default:
        rb_fatal("unknown enum rbs_type_param_variance value: %d", value);
    }
}

#ifdef RB_PASS_KEYWORDS
// Ruby 2.7 or later
#define CLASS_NEW_INSTANCE(klass, argc, argv) \
    rb_class_new_instance_kw(argc, argv, klass, RB_PASS_KEYWORDS)
#else
// Ruby 2.6
#define CLASS_NEW_INSTANCE(receiver, argc, argv) \
    rb_class_new_instance(argc, argv, receiver)
#endif

// Route Namespace / TypeName construction through the Ruby-side
// flyweight cache (`RBS::Namespace.[]` / `RBS::TypeName.[]`) so that
// structurally equal values produced by the parser share canonical
// instances. An in-C trie walk was tried but did not beat
// `rb_funcallv` on Ruby 4.0+, where method dispatch is well optimized.
static ID id_intern_brackets;

static inline ID intern_brackets(void) {
    if (!id_intern_brackets) id_intern_brackets = rb_intern("[]");
    return id_intern_brackets;
}

static VALUE rbs_intern_namespace(rbs_translation_context_t ctx, rbs_namespace_t *node) {
    VALUE args[2];
    args[0] = rbs_node_list_to_ruby_array(ctx, node->path);
    args[1] = node->absolute ? Qtrue : Qfalse;
    return rb_funcallv(RBS_Namespace, intern_brackets(), 2, args);
}

static VALUE rbs_intern_type_name(VALUE type_namespace, VALUE name) {
    VALUE args[2] = { type_namespace, name };
    return rb_funcallv(RBS_TypeName, intern_brackets(), 2, args);
}

VALUE rbs_struct_to_ruby_value(rbs_translation_context_t ctx, rbs_node_t *instance) {
    if (instance == NULL) return Qnil;

    switch (instance->type) {
    case RBS_AST_ANNOTATION: {
        rbs_ast_annotation_t *node = (rbs_ast_annotation_t *) instance;

        // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
        VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
        VALUE arg_string = rbs_string_to_ruby_string(&node->string, ctx.encoding);

        // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
        // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
        VALUE h = ctx.reusable_kwargs_hash;
        rb_hash_clear(h);
        rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
        rb_hash_aset(h, ID2SYM(rb_intern("string")), arg_string);
        return CLASS_NEW_INSTANCE(RBS_AST_Annotation, 1, &h);
    }
    case RBS_AST_BOOL: {
        return ((rbs_ast_bool_t *) instance)->value ? Qtrue : Qfalse;
    }
    case RBS_AST_COMMENT: {
        rbs_ast_comment_t *node = (rbs_ast_comment_t *) instance;

        // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
        VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
        VALUE arg_string = rbs_string_to_ruby_string(&node->string, ctx.encoding);

        // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
        // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
        VALUE h = ctx.reusable_kwargs_hash;
        rb_hash_clear(h);
        rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
        rb_hash_aset(h, ID2SYM(rb_intern("string")), arg_string);
        return CLASS_NEW_INSTANCE(RBS_AST_Comment, 1, &h);
    }
    case RBS_AST_DECLARATIONS_CLASS: {
        rbs_ast_declarations_class_t *node = (rbs_ast_declarations_class_t *) instance;

        // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
        VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
        rbs_loc *loc = rbs_check_location(arg_location);
        {
            rbs_loc_legacy_alloc_children(loc, 5);
            rbs_loc_legacy_add_required_child(loc, rb_intern("keyword"), (rbs_loc_range) { .start = node->keyword_range.start_char, .end = node->keyword_range.end_char });
            rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_char, .end = node->name_range.end_char });
            rbs_loc_legacy_add_required_child(loc, rb_intern("end"), (rbs_loc_range) { .start = node->end_range.start_char, .end = node->end_range.end_char });
            rbs_loc_legacy_add_optional_child(loc, rb_intern("type_params"), (rbs_loc_range) { .start = node->type_params_range.start_char, .end = node->type_params_range.end_char });
            rbs_loc_legacy_add_optional_child(loc, rb_intern("lt"), (rbs_loc_range) { .start = node->lt_range.start_char, .end = node->lt_range.end_char });
        }
        VALUE arg_name = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name); // rbs_type_name
        VALUE arg_type_params = rbs_node_list_to_ruby_array(ctx, node->type_params);
        VALUE arg_super_class = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->super_class); // rbs_ast_declarations_class_super
        VALUE arg_members = rbs_node_list_to_ruby_array(ctx, node->members);
        VALUE arg_annotations = rbs_node_list_to_ruby_array(ctx, node->annotations);
        VALUE arg_comment = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->comment); // rbs_ast_comment

        rb_funcall(
            RBS_AST_TypeParam,
            rb_intern("resolve_variables"),
            1,
            arg_type_params
        );
        // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
        // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
        VALUE h = ctx.reusable_kwargs_hash;
        rb_hash_clear(h);
        rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
        rb_hash_aset(h, ID2SYM(rb_intern("name")), arg_name);
        rb_hash_aset(h, ID2SYM(rb_intern("type_params")), arg_type_params);
        rb_hash_aset(h, ID2SYM(rb_intern("super_class")), arg_super_class);
        rb_hash_aset(h, ID2SYM(rb_intern("members")), arg_members);
        rb_hash_aset(h, ID2SYM(rb_intern("annotations")), arg_annotations);
        rb_hash_aset(h, ID2SYM(rb_intern("comment")), arg_comment);
        return CLASS_NEW_INSTANCE(RBS_AST_Declarations_Class, 1, &h);
    }
    case RBS_AST_DECLARATIONS_CLASS_SUPER: {
        rbs_ast_declarations_class_super_t *node = (rbs_ast_declarations_class_super_t *) instance;

        // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
        VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
        rbs_loc *loc = rbs_check_location(arg_location);
        {
            rbs_loc_legacy_alloc_children(loc, 2);
            rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_char, .end = node->name_range.end_char });
            rbs_loc_legacy_add_optional_child(loc, rb_intern("args"), (rbs_loc_range) { .start = node->args_range.start_char, .end = node->args_range.end_char });
        }
        VALUE arg_name = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name); // rbs_type_name
        VALUE arg_args = rbs_node_list_to_ruby_array(ctx, node->args);

        // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
        // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
        VALUE h = ctx.reusable_kwargs_hash;
        rb_hash_clear(h);
        rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
        rb_hash_aset(h, ID2SYM(rb_intern("name")), arg_name);
        rb_hash_aset(h, ID2SYM(rb_intern("args")), arg_args);
        return CLASS_NEW_INSTANCE(RBS_AST_Declarations_Class_Super, 1, &h);
    }
    case RBS_AST_DECLARATIONS_CLASS_ALIAS: {
        rbs_ast_declarations_class_alias_t *node = (rbs_ast_declarations_class_alias_t *) instance;

        // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
        VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
        rbs_loc *loc = rbs_check_location(arg_location);
        {
            rbs_loc_legacy_alloc_children(loc, 4);
            rbs_loc_legacy_add_required_child(loc, rb_intern("keyword"), (rbs_loc_range) { .start = node->keyword_range.start_char, .end = node->keyword_range.end_char });
            rbs_loc_legacy_add_required_child(loc, rb_intern("new_name"), (rbs_loc_range) { .start = node->new_name_range.start_char, .end = node->new_name_range.end_char });
            rbs_loc_legacy_add_required_child(loc, rb_intern("eq"), (rbs_loc_range) { .start = node->eq_range.start_char, .end = node->eq_range.end_char });
            rbs_loc_legacy_add_required_child(loc, rb_intern("old_name"), (rbs_loc_range) { .start = node->old_name_range.start_char, .end = node->old_name_range.end_char });
        }
        VALUE arg_new_name = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->new_name); // rbs_type_name
        VALUE arg_old_name = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->old_name); // rbs_type_name
        VALUE arg_comment = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->comment);   // rbs_ast_comment
        VALUE arg_annotations = rbs_node_list_to_ruby_array(ctx, node->annotations);

        // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
        // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
        VALUE h = ctx.reusable_kwargs_hash;
        rb_hash_clear(h);
        rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
        rb_hash_aset(h, ID2SYM(rb_intern("new_name")), arg_new_name);
        rb_hash_aset(h, ID2SYM(rb_intern("old_name")), arg_old_name);
        rb_hash_aset(h, ID2SYM(rb_intern("comment")), arg_comment);
        rb_hash_aset(h, ID2SYM(rb_intern("annotations")), arg_annotations);
        return CLASS_NEW_INSTANCE(RBS_AST_Declarations_ClassAlias, 1, &h);
    }
    case RBS_AST_DECLARATIONS_CONSTANT: {
        rbs_ast_declarations_constant_t *node = (rbs_ast_declarations_constant_t *) instance;

        // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
        VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
        rbs_loc *loc = rbs_check_location(arg_location);
        {
            rbs_loc_legacy_alloc_children(loc, 2);
            rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_char, .end = node->name_range.end_char });
            rbs_loc_legacy_add_required_child(loc, rb_intern("colon"), (rbs_loc_range) { .start = node->colon_range.start_char, .end = node->colon_range.end_char });
        }
        VALUE arg_name = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name);       // rbs_type_name
        VALUE arg_type = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->type);       // rbs_node
        VALUE arg_comment = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->comment); // rbs_ast_comment
        VALUE arg_annotations = rbs_node_list_to_ruby_array(ctx, node->annotations);

        // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
        // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
        VALUE h = ctx.reusable_kwargs_hash;
        rb_hash_clear(h);
        rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
        rb_hash_aset(h, ID2SYM(rb_intern("name")), arg_name);
        rb_hash_aset(h, ID2SYM(rb_intern("type")), arg_type);
        rb_hash_aset(h, ID2SYM(rb_intern("comment")), arg_comment);
        rb_hash_aset(h, ID2SYM(rb_intern("annotations")), arg_annotations);
        return CLASS_NEW_INSTANCE(RBS_AST_Declarations_Constant, 1, &h);
    }
    case RBS_AST_DECLARATIONS_GLOBAL: {
        rbs_ast_declarations_global_t *node = (rbs_ast_declarations_global_t *) instance;

        // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
        VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
        rbs_loc *loc = rbs_check_location(arg_location);
        {
            rbs_loc_legacy_alloc_children(loc, 2);
            rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_char, .end = node->name_range.end_char });
            rbs_loc_legacy_add_required_child(loc, rb_intern("colon"), (rbs_loc_range) { .start = node->colon_range.start_char, .end = node->colon_range.end_char });
        }
        VALUE arg_name = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name);       // rbs_ast_symbol
        VALUE arg_type = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->type);       // rbs_node
        VALUE arg_comment = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->comment); // rbs_ast_comment
        VALUE arg_annotations = rbs_node_list_to_ruby_array(ctx, node->annotations);

        // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
        // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
        VALUE h = ctx.reusable_kwargs_hash;
        rb_hash_clear(h);
        rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
        rb_hash_aset(h, ID2SYM(rb_intern("name")), arg_name);
        rb_hash_aset(h, ID2SYM(rb_intern("type")), arg_type);
        rb_hash_aset(h, ID2SYM(rb_intern("comment")), arg_comment);
        rb_hash_aset(h, ID2SYM(rb_intern("annotations")), arg_annotations);
        return CLASS_NEW_INSTANCE(RBS_AST_Declarations_Global, 1, &h);
    }
    case RBS_AST_DECLARATIONS_INTERFACE: {
        rbs_ast_declarations_interface_t *node = (rbs_ast_declarations_interface_t *) instance;

        // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
        VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
        rbs_loc *loc = rbs_check_location(arg_location);
        {
            rbs_loc_legacy_alloc_children(loc, 4);
            rbs_loc_legacy_add_required_child(loc, rb_intern("keyword"), (rbs_loc_range) { .start = node->keyword_range.start_char, .end = node->keyword_range.end_char });
            rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_char, .end = node->name_range.end_char });
            rbs_loc_legacy_add_required_child(loc, rb_intern("end"), (rbs_loc_range) { .start = node->end_range.start_char, .end = node->end_range.end_char });
            rbs_loc_legacy_add_optional_child(loc, rb_intern("type_params"), (rbs_loc_range) { .start = node->type_params_range.start_char, .end = node->type_params_range.end_char });
        }
        VALUE arg_name = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name); // rbs_type_name
        VALUE arg_type_params = rbs_node_list_to_ruby_array(ctx, node->type_params);
        VALUE arg_members = rbs_node_list_to_ruby_array(ctx, node->members);
        VALUE arg_annotations = rbs_node_list_to_ruby_array(ctx, node->annotations);
        VALUE arg_comment = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->comment); // rbs_ast_comment

        rb_funcall(
            RBS_AST_TypeParam,
            rb_intern("resolve_variables"),
            1,
            arg_type_params
        );
        // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
        // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
        VALUE h = ctx.reusable_kwargs_hash;
        rb_hash_clear(h);
        rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
        rb_hash_aset(h, ID2SYM(rb_intern("name")), arg_name);
        rb_hash_aset(h, ID2SYM(rb_intern("type_params")), arg_type_params);
        rb_hash_aset(h, ID2SYM(rb_intern("members")), arg_members);
        rb_hash_aset(h, ID2SYM(rb_intern("annotations")), arg_annotations);
        rb_hash_aset(h, ID2SYM(rb_intern("comment")), arg_comment);
        return CLASS_NEW_INSTANCE(RBS_AST_Declarations_Interface, 1, &h);
    }
    case RBS_AST_DECLARATIONS_MODULE: {
        rbs_ast_declarations_module_t *node = (rbs_ast_declarations_module_t *) instance;

        // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
        VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
        rbs_loc *loc = rbs_check_location(arg_location);
        {
            rbs_loc_legacy_alloc_children(loc, 6);
            rbs_loc_legacy_add_required_child(loc, rb_intern("keyword"), (rbs_loc_range) { .start = node->keyword_range.start_char, .end = node->keyword_range.end_char });
            rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_char, .end = node->name_range.end_char });
            rbs_loc_legacy_add_required_child(loc, rb_intern("end"), (rbs_loc_range) { .start = node->end_range.start_char, .end = node->end_range.end_char });
            rbs_loc_legacy_add_optional_child(loc, rb_intern("type_params"), (rbs_loc_range) { .start = node->type_params_range.start_char, .end = node->type_params_range.end_char });
            rbs_loc_legacy_add_optional_child(loc, rb_intern("colon"), (rbs_loc_range) { .start = node->colon_range.start_char, .end = node->colon_range.end_char });
            rbs_loc_legacy_add_optional_child(loc, rb_intern("self_types"), (rbs_loc_range) { .start = node->self_types_range.start_char, .end = node->self_types_range.end_char });
        }
        VALUE arg_name = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name); // rbs_type_name
        VALUE arg_type_params = rbs_node_list_to_ruby_array(ctx, node->type_params);
        VALUE arg_self_types = rbs_node_list_to_ruby_array(ctx, node->self_types);
        VALUE arg_members = rbs_node_list_to_ruby_array(ctx, node->members);
        VALUE arg_annotations = rbs_node_list_to_ruby_array(ctx, node->annotations);
        VALUE arg_comment = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->comment); // rbs_ast_comment

        rb_funcall(
            RBS_AST_TypeParam,
            rb_intern("resolve_variables"),
            1,
            arg_type_params
        );
        // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
        // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
        VALUE h = ctx.reusable_kwargs_hash;
        rb_hash_clear(h);
        rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
        rb_hash_aset(h, ID2SYM(rb_intern("name")), arg_name);
        rb_hash_aset(h, ID2SYM(rb_intern("type_params")), arg_type_params);
        rb_hash_aset(h, ID2SYM(rb_intern("self_types")), arg_self_types);
        rb_hash_aset(h, ID2SYM(rb_intern("members")), arg_members);
        rb_hash_aset(h, ID2SYM(rb_intern("annotations")), arg_annotations);
        rb_hash_aset(h, ID2SYM(rb_intern("comment")), arg_comment);
        return CLASS_NEW_INSTANCE(RBS_AST_Declarations_Module, 1, &h);
    }
    case RBS_AST_DECLARATIONS_MODULE_SELF: {
        rbs_ast_declarations_module_self_t *node = (rbs_ast_declarations_module_self_t *) instance;

        // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
        VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
        rbs_loc *loc = rbs_check_location(arg_location);
        {
            rbs_loc_legacy_alloc_children(loc, 2);
            rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_char, .end = node->name_range.end_char });
            rbs_loc_legacy_add_optional_child(loc, rb_intern("args"), (rbs_loc_range) { .start = node->args_range.start_char, .end = node->args_range.end_char });
        }
        VALUE arg_name = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name); // rbs_type_name
        VALUE arg_args = rbs_node_list_to_ruby_array(ctx, node->args);

        // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
        // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
        VALUE h = ctx.reusable_kwargs_hash;
        rb_hash_clear(h);
        rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
        rb_hash_aset(h, ID2SYM(rb_intern("name")), arg_name);
        rb_hash_aset(h, ID2SYM(rb_intern("args")), arg_args);
        return CLASS_NEW_INSTANCE(RBS_AST_Declarations_Module_Self, 1, &h);
    }
    case RBS_AST_DECLARATIONS_MODULE_ALIAS: {
        rbs_ast_declarations_module_alias_t *node = (rbs_ast_declarations_module_alias_t *) instance;

        // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
        VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
        rbs_loc *loc = rbs_check_location(arg_location);
        {
            rbs_loc_legacy_alloc_children(loc, 4);
            rbs_loc_legacy_add_required_child(loc, rb_intern("keyword"), (rbs_loc_range) { .start = node->keyword_range.start_char, .end = node->keyword_range.end_char });
            rbs_loc_legacy_add_required_child(loc, rb_intern("new_name"), (rbs_loc_range) { .start = node->new_name_range.start_char, .end = node->new_name_range.end_char });
            rbs_loc_legacy_add_required_child(loc, rb_intern("eq"), (rbs_loc_range) { .start = node->eq_range.start_char, .end = node->eq_range.end_char });
            rbs_loc_legacy_add_required_child(loc, rb_intern("old_name"), (rbs_loc_range) { .start = node->old_name_range.start_char, .end = node->old_name_range.end_char });
        }
        VALUE arg_new_name = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->new_name); // rbs_type_name
        VALUE arg_old_name = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->old_name); // rbs_type_name
        VALUE arg_comment = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->comment);   // rbs_ast_comment
        VALUE arg_annotations = rbs_node_list_to_ruby_array(ctx, node->annotations);

        // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
        // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
        VALUE h = ctx.reusable_kwargs_hash;
        rb_hash_clear(h);
        rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
        rb_hash_aset(h, ID2SYM(rb_intern("new_name")), arg_new_name);
        rb_hash_aset(h, ID2SYM(rb_intern("old_name")), arg_old_name);
        rb_hash_aset(h, ID2SYM(rb_intern("comment")), arg_comment);
        rb_hash_aset(h, ID2SYM(rb_intern("annotations")), arg_annotations);
        return CLASS_NEW_INSTANCE(RBS_AST_Declarations_ModuleAlias, 1, &h);
    }
    case RBS_AST_DECLARATIONS_TYPE_ALIAS: {
        rbs_ast_declarations_type_alias_t *node = (rbs_ast_declarations_type_alias_t *) instance;

        // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
        VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
        rbs_loc *loc = rbs_check_location(arg_location);
        {
            rbs_loc_legacy_alloc_children(loc, 4);
            rbs_loc_legacy_add_required_child(loc, rb_intern("keyword"), (rbs_loc_range) { .start = node->keyword_range.start_char, .end = node->keyword_range.end_char });
            rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_char, .end = node->name_range.end_char });
            rbs_loc_legacy_add_required_child(loc, rb_intern("eq"), (rbs_loc_range) { .start = node->eq_range.start_char, .end = node->eq_range.end_char });
            rbs_loc_legacy_add_optional_child(loc, rb_intern("type_params"), (rbs_loc_range) { .start = node->type_params_range.start_char, .end = node->type_params_range.end_char });
        }
        VALUE arg_name = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name); // rbs_type_name
        VALUE arg_type_params = rbs_node_list_to_ruby_array(ctx, node->type_params);
        VALUE arg_type = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->type); // rbs_node
        VALUE arg_annotations = rbs_node_list_to_ruby_array(ctx, node->annotations);
        VALUE arg_comment = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->comment); // rbs_ast_comment

        rb_funcall(
            RBS_AST_TypeParam,
            rb_intern("resolve_variables"),
            1,
            arg_type_params
        );
        // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
        // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
        VALUE h = ctx.reusable_kwargs_hash;
        rb_hash_clear(h);
        rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
        rb_hash_aset(h, ID2SYM(rb_intern("name")), arg_name);
        rb_hash_aset(h, ID2SYM(rb_intern("type_params")), arg_type_params);
        rb_hash_aset(h, ID2SYM(rb_intern("type")), arg_type);
        rb_hash_aset(h, ID2SYM(rb_intern("annotations")), arg_annotations);
        rb_hash_aset(h, ID2SYM(rb_intern("comment")), arg_comment);
        return CLASS_NEW_INSTANCE(RBS_AST_Declarations_TypeAlias, 1, &h);
    }
    case RBS_AST_DIRECTIVES_USE: {
        rbs_ast_directives_use_t *node = (rbs_ast_directives_use_t *) instance;

        // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
        VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
        rbs_loc *loc = rbs_check_location(arg_location);
        {
            rbs_loc_legacy_alloc_children(loc, 1);
            rbs_loc_legacy_add_required_child(loc, rb_intern("keyword"), (rbs_loc_range) { .start = node->keyword_range.start_char, .end = node->keyword_range.end_char });
        }
        VALUE arg_clauses = rbs_node_list_to_ruby_array(ctx, node->clauses);

        // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
        // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
        VALUE h = ctx.reusable_kwargs_hash;
        rb_hash_clear(h);
        rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
        rb_hash_aset(h, ID2SYM(rb_intern("clauses")), arg_clauses);
        return CLASS_NEW_INSTANCE(RBS_AST_Directives_Use, 1, &h);
    }
    case RBS_AST_DIRECTIVES_USE_SINGLE_CLAUSE: {
        rbs_ast_directives_use_single_clause_t *node = (rbs_ast_directives_use_single_clause_t *) instance;

        // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
        VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
        rbs_loc *loc = rbs_check_location(arg_location);
        {
            rbs_loc_legacy_alloc_children(loc, 3);
            rbs_loc_legacy_add_required_child(loc, rb_intern("type_name"), (rbs_loc_range) { .start = node->type_name_range.start_char, .end = node->type_name_range.end_char });
            rbs_loc_legacy_add_optional_child(loc, rb_intern("keyword"), (rbs_loc_range) { .start = node->keyword_range.start_char, .end = node->keyword_range.end_char });
            rbs_loc_legacy_add_optional_child(loc, rb_intern("new_name"), (rbs_loc_range) { .start = node->new_name_range.start_char, .end = node->new_name_range.end_char });
        }
        VALUE arg_type_name = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->type_name); // rbs_type_name
        VALUE arg_new_name = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->new_name);   // rbs_ast_symbol

        // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
        // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
        VALUE h = ctx.reusable_kwargs_hash;
        rb_hash_clear(h);
        rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
        rb_hash_aset(h, ID2SYM(rb_intern("type_name")), arg_type_name);
        rb_hash_aset(h, ID2SYM(rb_intern("new_name")), arg_new_name);
        return CLASS_NEW_INSTANCE(RBS_AST_Directives_Use_SingleClause, 1, &h);
    }
    case RBS_AST_DIRECTIVES_USE_WILDCARD_CLAUSE: {
        rbs_ast_directives_use_wildcard_clause_t *node = (rbs_ast_directives_use_wildcard_clause_t *) instance;

        // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
        VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
        rbs_loc *loc = rbs_check_location(arg_location);
        {
            rbs_loc_legacy_alloc_children(loc, 2);
            rbs_loc_legacy_add_required_child(loc, rb_intern("namespace"), (rbs_loc_range) { .start = node->namespace_range.start_char, .end = node->namespace_range.end_char });
            rbs_loc_legacy_add_required_child(loc, rb_intern("star"), (rbs_loc_range) { .start = node->star_range.start_char, .end = node->star_range.end_char });
        }
        VALUE arg_namespace = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->rbs_namespace); // rbs_namespace

        // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
        // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
        VALUE h = ctx.reusable_kwargs_hash;
        rb_hash_clear(h);
        rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
        rb_hash_aset(h, ID2SYM(rb_intern("namespace")), arg_namespace);
        return CLASS_NEW_INSTANCE(RBS_AST_Directives_Use_WildcardClause, 1, &h);
    }
    case RBS_AST_INTEGER: {
        rbs_ast_integer_t *integer_node = (rbs_ast_integer_t *) instance;
        rbs_string_t string_repr = integer_node->string_representation;

        VALUE str = rb_enc_str_new(string_repr.start, rbs_string_len(string_repr), rb_utf8_encoding());

        return rb_funcall(str, rb_intern("to_i"), 0);
    }
    case RBS_AST_MEMBERS_ALIAS: {
        rbs_ast_members_alias_t *node = (rbs_ast_members_alias_t *) instance;

        // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
        VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
        rbs_loc *loc = rbs_check_location(arg_location);
        {
            rbs_loc_legacy_alloc_children(loc, 5);
            rbs_loc_legacy_add_required_child(loc, rb_intern("keyword"), (rbs_loc_range) { .start = node->keyword_range.start_char, .end = node->keyword_range.end_char });
            rbs_loc_legacy_add_required_child(loc, rb_intern("new_name"), (rbs_loc_range) { .start = node->new_name_range.start_char, .end = node->new_name_range.end_char });
            rbs_loc_legacy_add_required_child(loc, rb_intern("old_name"), (rbs_loc_range) { .start = node->old_name_range.start_char, .end = node->old_name_range.end_char });
            rbs_loc_legacy_add_optional_child(loc, rb_intern("new_kind"), (rbs_loc_range) { .start = node->new_kind_range.start_char, .end = node->new_kind_range.end_char });
            rbs_loc_legacy_add_optional_child(loc, rb_intern("old_kind"), (rbs_loc_range) { .start = node->old_kind_range.start_char, .end = node->old_kind_range.end_char });
        }
        VALUE arg_new_name = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->new_name); // rbs_ast_symbol
        VALUE arg_old_name = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->old_name); // rbs_ast_symbol
        VALUE arg_kind = rbs_alias_kind_to_ruby(node->kind);                               // alias_kind
        VALUE arg_annotations = rbs_node_list_to_ruby_array(ctx, node->annotations);
        VALUE arg_comment = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->comment); // rbs_ast_comment

        // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
        // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
        VALUE h = ctx.reusable_kwargs_hash;
        rb_hash_clear(h);
        rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
        rb_hash_aset(h, ID2SYM(rb_intern("new_name")), arg_new_name);
        rb_hash_aset(h, ID2SYM(rb_intern("old_name")), arg_old_name);
        rb_hash_aset(h, ID2SYM(rb_intern("kind")), arg_kind);
        rb_hash_aset(h, ID2SYM(rb_intern("annotations")), arg_annotations);
        rb_hash_aset(h, ID2SYM(rb_intern("comment")), arg_comment);
        return CLASS_NEW_INSTANCE(RBS_AST_Members_Alias, 1, &h);
    }
    case RBS_AST_MEMBERS_ATTR_ACCESSOR: {
        rbs_ast_members_attr_accessor_t *node = (rbs_ast_members_attr_accessor_t *) instance;

        // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
        VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
        rbs_loc *loc = rbs_check_location(arg_location);
        {
            rbs_loc_legacy_alloc_children(loc, 7);
            rbs_loc_legacy_add_required_child(loc, rb_intern("keyword"), (rbs_loc_range) { .start = node->keyword_range.start_char, .end = node->keyword_range.end_char });
            rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_char, .end = node->name_range.end_char });
            rbs_loc_legacy_add_required_child(loc, rb_intern("colon"), (rbs_loc_range) { .start = node->colon_range.start_char, .end = node->colon_range.end_char });
            rbs_loc_legacy_add_optional_child(loc, rb_intern("kind"), (rbs_loc_range) { .start = node->kind_range.start_char, .end = node->kind_range.end_char });
            rbs_loc_legacy_add_optional_child(loc, rb_intern("ivar"), (rbs_loc_range) { .start = node->ivar_range.start_char, .end = node->ivar_range.end_char });
            rbs_loc_legacy_add_optional_child(loc, rb_intern("ivar_name"), (rbs_loc_range) { .start = node->ivar_name_range.start_char, .end = node->ivar_name_range.end_char });
            rbs_loc_legacy_add_optional_child(loc, rb_intern("visibility"), (rbs_loc_range) { .start = node->visibility_range.start_char, .end = node->visibility_range.end_char });
        }
        VALUE arg_name = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name); // rbs_ast_symbol
        VALUE arg_type = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->type); // rbs_node
        VALUE arg_ivar_name = rbs_attr_ivar_name_to_ruby(ctx, node->ivar_name);    // rbs_attr_ivar_name_t
        VALUE arg_kind = rbs_attribute_kind_to_ruby(node->kind);                   // attribute_kind
        VALUE arg_annotations = rbs_node_list_to_ruby_array(ctx, node->annotations);
        VALUE arg_comment = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->comment); // rbs_ast_comment
        VALUE arg_visibility = rbs_attribute_visibility_to_ruby(node->visibility);       // attribute_visibility

        // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
        // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
        VALUE h = ctx.reusable_kwargs_hash;
        rb_hash_clear(h);
        rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
        rb_hash_aset(h, ID2SYM(rb_intern("name")), arg_name);
        rb_hash_aset(h, ID2SYM(rb_intern("type")), arg_type);
        rb_hash_aset(h, ID2SYM(rb_intern("ivar_name")), arg_ivar_name);
        rb_hash_aset(h, ID2SYM(rb_intern("kind")), arg_kind);
        rb_hash_aset(h, ID2SYM(rb_intern("annotations")), arg_annotations);
        rb_hash_aset(h, ID2SYM(rb_intern("comment")), arg_comment);
        rb_hash_aset(h, ID2SYM(rb_intern("visibility")), arg_visibility);
        return CLASS_NEW_INSTANCE(RBS_AST_Members_AttrAccessor, 1, &h);
    }
    case RBS_AST_MEMBERS_ATTR_READER: {
        rbs_ast_members_attr_reader_t *node = (rbs_ast_members_attr_reader_t *) instance;

        // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
        VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
        rbs_loc *loc = rbs_check_location(arg_location);
        {
            rbs_loc_legacy_alloc_children(loc, 7);
            rbs_loc_legacy_add_required_child(loc, rb_intern("keyword"), (rbs_loc_range) { .start = node->keyword_range.start_char, .end = node->keyword_range.end_char });
            rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_char, .end = node->name_range.end_char });
            rbs_loc_legacy_add_required_child(loc, rb_intern("colon"), (rbs_loc_range) { .start = node->colon_range.start_char, .end = node->colon_range.end_char });
            rbs_loc_legacy_add_optional_child(loc, rb_intern("kind"), (rbs_loc_range) { .start = node->kind_range.start_char, .end = node->kind_range.end_char });
            rbs_loc_legacy_add_optional_child(loc, rb_intern("ivar"), (rbs_loc_range) { .start = node->ivar_range.start_char, .end = node->ivar_range.end_char });
            rbs_loc_legacy_add_optional_child(loc, rb_intern("ivar_name"), (rbs_loc_range) { .start = node->ivar_name_range.start_char, .end = node->ivar_name_range.end_char });
            rbs_loc_legacy_add_optional_child(loc, rb_intern("visibility"), (rbs_loc_range) { .start = node->visibility_range.start_char, .end = node->visibility_range.end_char });
        }
        VALUE arg_name = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name); // rbs_ast_symbol
        VALUE arg_type = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->type); // rbs_node
        VALUE arg_ivar_name = rbs_attr_ivar_name_to_ruby(ctx, node->ivar_name);    // rbs_attr_ivar_name_t
        VALUE arg_kind = rbs_attribute_kind_to_ruby(node->kind);                   // attribute_kind
        VALUE arg_annotations = rbs_node_list_to_ruby_array(ctx, node->annotations);
        VALUE arg_comment = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->comment); // rbs_ast_comment
        VALUE arg_visibility = rbs_attribute_visibility_to_ruby(node->visibility);       // attribute_visibility

        // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
        // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
        VALUE h = ctx.reusable_kwargs_hash;
        rb_hash_clear(h);
        rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
        rb_hash_aset(h, ID2SYM(rb_intern("name")), arg_name);
        rb_hash_aset(h, ID2SYM(rb_intern("type")), arg_type);
        rb_hash_aset(h, ID2SYM(rb_intern("ivar_name")), arg_ivar_name);
        rb_hash_aset(h, ID2SYM(rb_intern("kind")), arg_kind);
        rb_hash_aset(h, ID2SYM(rb_intern("annotations")), arg_annotations);
        rb_hash_aset(h, ID2SYM(rb_intern("comment")), arg_comment);
        rb_hash_aset(h, ID2SYM(rb_intern("visibility")), arg_visibility);
        return CLASS_NEW_INSTANCE(RBS_AST_Members_AttrReader, 1, &h);
    }
    case RBS_AST_MEMBERS_ATTR_WRITER: {
        rbs_ast_members_attr_writer_t *node = (rbs_ast_members_attr_writer_t *) instance;

        // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
        VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
        rbs_loc *loc = rbs_check_location(arg_location);
        {
            rbs_loc_legacy_alloc_children(loc, 7);
            rbs_loc_legacy_add_required_child(loc, rb_intern("keyword"), (rbs_loc_range) { .start = node->keyword_range.start_char, .end = node->keyword_range.end_char });
            rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_char, .end = node->name_range.end_char });
            rbs_loc_legacy_add_required_child(loc, rb_intern("colon"), (rbs_loc_range) { .start = node->colon_range.start_char, .end = node->colon_range.end_char });
            rbs_loc_legacy_add_optional_child(loc, rb_intern("kind"), (rbs_loc_range) { .start = node->kind_range.start_char, .end = node->kind_range.end_char });
            rbs_loc_legacy_add_optional_child(loc, rb_intern("ivar"), (rbs_loc_range) { .start = node->ivar_range.start_char, .end = node->ivar_range.end_char });
            rbs_loc_legacy_add_optional_child(loc, rb_intern("ivar_name"), (rbs_loc_range) { .start = node->ivar_name_range.start_char, .end = node->ivar_name_range.end_char });
            rbs_loc_legacy_add_optional_child(loc, rb_intern("visibility"), (rbs_loc_range) { .start = node->visibility_range.start_char, .end = node->visibility_range.end_char });
        }
        VALUE arg_name = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name); // rbs_ast_symbol
        VALUE arg_type = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->type); // rbs_node
        VALUE arg_ivar_name = rbs_attr_ivar_name_to_ruby(ctx, node->ivar_name);    // rbs_attr_ivar_name_t
        VALUE arg_kind = rbs_attribute_kind_to_ruby(node->kind);                   // attribute_kind
        VALUE arg_annotations = rbs_node_list_to_ruby_array(ctx, node->annotations);
        VALUE arg_comment = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->comment); // rbs_ast_comment
        VALUE arg_visibility = rbs_attribute_visibility_to_ruby(node->visibility);       // attribute_visibility

        // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
        // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
        VALUE h = ctx.reusable_kwargs_hash;
        rb_hash_clear(h);
        rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
        rb_hash_aset(h, ID2SYM(rb_intern("name")), arg_name);
        rb_hash_aset(h, ID2SYM(rb_intern("type")), arg_type);
        rb_hash_aset(h, ID2SYM(rb_intern("ivar_name")), arg_ivar_name);
        rb_hash_aset(h, ID2SYM(rb_intern("kind")), arg_kind);
        rb_hash_aset(h, ID2SYM(rb_intern("annotations")), arg_annotations);
        rb_hash_aset(h, ID2SYM(rb_intern("comment")), arg_comment);
        rb_hash_aset(h, ID2SYM(rb_intern("visibility")), arg_visibility);
        return CLASS_NEW_INSTANCE(RBS_AST_Members_AttrWriter, 1, &h);
    }
    case RBS_AST_MEMBERS_CLASS_INSTANCE_VARIABLE: {
        rbs_ast_members_class_instance_variable_t *node = (rbs_ast_members_class_instance_variable_t *) instance;

        // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
        VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
        rbs_loc *loc = rbs_check_location(arg_location);
        {
            rbs_loc_legacy_alloc_children(loc, 3);
            rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_char, .end = node->name_range.end_char });
            rbs_loc_legacy_add_required_child(loc, rb_intern("colon"), (rbs_loc_range) { .start = node->colon_range.start_char, .end = node->colon_range.end_char });
            rbs_loc_legacy_add_optional_child(loc, rb_intern("kind"), (rbs_loc_range) { .start = node->kind_range.start_char, .end = node->kind_range.end_char });
        }
        VALUE arg_name = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name);       // rbs_ast_symbol
        VALUE arg_type = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->type);       // rbs_node
        VALUE arg_comment = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->comment); // rbs_ast_comment

        // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
        // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
        VALUE h = ctx.reusable_kwargs_hash;
        rb_hash_clear(h);
        rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
        rb_hash_aset(h, ID2SYM(rb_intern("name")), arg_name);
        rb_hash_aset(h, ID2SYM(rb_intern("type")), arg_type);
        rb_hash_aset(h, ID2SYM(rb_intern("comment")), arg_comment);
        return CLASS_NEW_INSTANCE(RBS_AST_Members_ClassInstanceVariable, 1, &h);
    }
    case RBS_AST_MEMBERS_CLASS_VARIABLE: {
        rbs_ast_members_class_variable_t *node = (rbs_ast_members_class_variable_t *) instance;

        // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
        VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
        rbs_loc *loc = rbs_check_location(arg_location);
        {
            rbs_loc_legacy_alloc_children(loc, 3);
            rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_char, .end = node->name_range.end_char });
            rbs_loc_legacy_add_required_child(loc, rb_intern("colon"), (rbs_loc_range) { .start = node->colon_range.start_char, .end = node->colon_range.end_char });
            rbs_loc_legacy_add_optional_child(loc, rb_intern("kind"), (rbs_loc_range) { .start = node->kind_range.start_char, .end = node->kind_range.end_char });
        }
        VALUE arg_name = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name);       // rbs_ast_symbol
        VALUE arg_type = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->type);       // rbs_node
        VALUE arg_comment = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->comment); // rbs_ast_comment

        // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
        // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
        VALUE h = ctx.reusable_kwargs_hash;
        rb_hash_clear(h);
        rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
        rb_hash_aset(h, ID2SYM(rb_intern("name")), arg_name);
        rb_hash_aset(h, ID2SYM(rb_intern("type")), arg_type);
        rb_hash_aset(h, ID2SYM(rb_intern("comment")), arg_comment);
        return CLASS_NEW_INSTANCE(RBS_AST_Members_ClassVariable, 1, &h);
    }
    case RBS_AST_MEMBERS_EXTEND: {
        rbs_ast_members_extend_t *node = (rbs_ast_members_extend_t *) instance;

        // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
        VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
        rbs_loc *loc = rbs_check_location(arg_location);
        {
            rbs_loc_legacy_alloc_children(loc, 3);
            rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_char, .end = node->name_range.end_char });
            rbs_loc_legacy_add_required_child(loc, rb_intern("keyword"), (rbs_loc_range) { .start = node->keyword_range.start_char, .end = node->keyword_range.end_char });
            rbs_loc_legacy_add_optional_child(loc, rb_intern("args"), (rbs_loc_range) { .start = node->args_range.start_char, .end = node->args_range.end_char });
        }
        VALUE arg_name = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name); // rbs_type_name
        VALUE arg_args = rbs_node_list_to_ruby_array(ctx, node->args);
        VALUE arg_annotations = rbs_node_list_to_ruby_array(ctx, node->annotations);
        VALUE arg_comment = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->comment); // rbs_ast_comment

        // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
        // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
        VALUE h = ctx.reusable_kwargs_hash;
        rb_hash_clear(h);
        rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
        rb_hash_aset(h, ID2SYM(rb_intern("name")), arg_name);
        rb_hash_aset(h, ID2SYM(rb_intern("args")), arg_args);
        rb_hash_aset(h, ID2SYM(rb_intern("annotations")), arg_annotations);
        rb_hash_aset(h, ID2SYM(rb_intern("comment")), arg_comment);
        return CLASS_NEW_INSTANCE(RBS_AST_Members_Extend, 1, &h);
    }
    case RBS_AST_MEMBERS_INCLUDE: {
        rbs_ast_members_include_t *node = (rbs_ast_members_include_t *) instance;

        // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
        VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
        rbs_loc *loc = rbs_check_location(arg_location);
        {
            rbs_loc_legacy_alloc_children(loc, 3);
            rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_char, .end = node->name_range.end_char });
            rbs_loc_legacy_add_required_child(loc, rb_intern("keyword"), (rbs_loc_range) { .start = node->keyword_range.start_char, .end = node->keyword_range.end_char });
            rbs_loc_legacy_add_optional_child(loc, rb_intern("args"), (rbs_loc_range) { .start = node->args_range.start_char, .end = node->args_range.end_char });
        }
        VALUE arg_name = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name); // rbs_type_name
        VALUE arg_args = rbs_node_list_to_ruby_array(ctx, node->args);
        VALUE arg_annotations = rbs_node_list_to_ruby_array(ctx, node->annotations);
        VALUE arg_comment = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->comment); // rbs_ast_comment

        // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
        // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
        VALUE h = ctx.reusable_kwargs_hash;
        rb_hash_clear(h);
        rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
        rb_hash_aset(h, ID2SYM(rb_intern("name")), arg_name);
        rb_hash_aset(h, ID2SYM(rb_intern("args")), arg_args);
        rb_hash_aset(h, ID2SYM(rb_intern("annotations")), arg_annotations);
        rb_hash_aset(h, ID2SYM(rb_intern("comment")), arg_comment);
        return CLASS_NEW_INSTANCE(RBS_AST_Members_Include, 1, &h);
    }
    case RBS_AST_MEMBERS_INSTANCE_VARIABLE: {
        rbs_ast_members_instance_variable_t *node = (rbs_ast_members_instance_variable_t *) instance;

        // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
        VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
        rbs_loc *loc = rbs_check_location(arg_location);
        {
            rbs_loc_legacy_alloc_children(loc, 3);
            rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_char, .end = node->name_range.end_char });
            rbs_loc_legacy_add_required_child(loc, rb_intern("colon"), (rbs_loc_range) { .start = node->colon_range.start_char, .end = node->colon_range.end_char });
            rbs_loc_legacy_add_optional_child(loc, rb_intern("kind"), (rbs_loc_range) { .start = node->kind_range.start_char, .end = node->kind_range.end_char });
        }
        VALUE arg_name = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name);       // rbs_ast_symbol
        VALUE arg_type = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->type);       // rbs_node
        VALUE arg_comment = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->comment); // rbs_ast_comment

        // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
        // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
        VALUE h = ctx.reusable_kwargs_hash;
        rb_hash_clear(h);
        rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
        rb_hash_aset(h, ID2SYM(rb_intern("name")), arg_name);
        rb_hash_aset(h, ID2SYM(rb_intern("type")), arg_type);
        rb_hash_aset(h, ID2SYM(rb_intern("comment")), arg_comment);
        return CLASS_NEW_INSTANCE(RBS_AST_Members_InstanceVariable, 1, &h);
    }
    case RBS_AST_MEMBERS_METHOD_DEFINITION: {
        rbs_ast_members_method_definition_t *node = (rbs_ast_members_method_definition_t *) instance;

        // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
        VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
        rbs_loc *loc = rbs_check_location(arg_location);
        {
            rbs_loc_legacy_alloc_children(loc, 5);
            rbs_loc_legacy_add_required_child(loc, rb_intern("keyword"), (rbs_loc_range) { .start = node->keyword_range.start_char, .end = node->keyword_range.end_char });
            rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_char, .end = node->name_range.end_char });
            rbs_loc_legacy_add_optional_child(loc, rb_intern("kind"), (rbs_loc_range) { .start = node->kind_range.start_char, .end = node->kind_range.end_char });
            rbs_loc_legacy_add_optional_child(loc, rb_intern("overloading"), (rbs_loc_range) { .start = node->overloading_range.start_char, .end = node->overloading_range.end_char });
            rbs_loc_legacy_add_optional_child(loc, rb_intern("visibility"), (rbs_loc_range) { .start = node->visibility_range.start_char, .end = node->visibility_range.end_char });
        }
        VALUE arg_name = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name); // rbs_ast_symbol
        VALUE arg_kind = rbs_method_definition_kind_to_ruby(node->kind);           // method_definition_kind
        VALUE arg_overloads = rbs_node_list_to_ruby_array(ctx, node->overloads);
        VALUE arg_annotations = rbs_node_list_to_ruby_array(ctx, node->annotations);
        VALUE arg_comment = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->comment); // rbs_ast_comment
        VALUE arg_overloading = node->overloading ? Qtrue : Qfalse;
        VALUE arg_visibility = rbs_method_definition_visibility_to_ruby(node->visibility); // method_definition_visibility

        // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
        // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
        VALUE h = ctx.reusable_kwargs_hash;
        rb_hash_clear(h);
        rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
        rb_hash_aset(h, ID2SYM(rb_intern("name")), arg_name);
        rb_hash_aset(h, ID2SYM(rb_intern("kind")), arg_kind);
        rb_hash_aset(h, ID2SYM(rb_intern("overloads")), arg_overloads);
        rb_hash_aset(h, ID2SYM(rb_intern("annotations")), arg_annotations);
        rb_hash_aset(h, ID2SYM(rb_intern("comment")), arg_comment);
        rb_hash_aset(h, ID2SYM(rb_intern("overloading")), arg_overloading);
        rb_hash_aset(h, ID2SYM(rb_intern("visibility")), arg_visibility);
        return CLASS_NEW_INSTANCE(RBS_AST_Members_MethodDefinition, 1, &h);
    }
    case RBS_AST_MEMBERS_METHOD_DEFINITION_OVERLOAD: {
        rbs_ast_members_method_definition_overload_t *node = (rbs_ast_members_method_definition_overload_t *) instance;

        // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
        VALUE arg_annotations = rbs_node_list_to_ruby_array(ctx, node->annotations);
        VALUE arg_method_type = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->method_type); // rbs_node

        // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
        // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
        VALUE h = ctx.reusable_kwargs_hash;
        rb_hash_clear(h);
        rb_hash_aset(h, ID2SYM(rb_intern("annotations")), arg_annotations);
        rb_hash_aset(h, ID2SYM(rb_intern("method_type")), arg_method_type);
        return CLASS_NEW_INSTANCE(RBS_AST_Members_MethodDefinition_Overload, 1, &h);
    }
    case RBS_AST_MEMBERS_PREPEND: {
        rbs_ast_members_prepend_t *node = (rbs_ast_members_prepend_t *) instance;

        // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
        VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
        rbs_loc *loc = rbs_check_location(arg_location);
        {
            rbs_loc_legacy_alloc_children(loc, 3);
            rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_char, .end = node->name_range.end_char });
            rbs_loc_legacy_add_required_child(loc, rb_intern("keyword"), (rbs_loc_range) { .start = node->keyword_range.start_char, .end = node->keyword_range.end_char });
            rbs_loc_legacy_add_optional_child(loc, rb_intern("args"), (rbs_loc_range) { .start = node->args_range.start_char, .end = node->args_range.end_char });
        }
        VALUE arg_name = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name); // rbs_type_name
        VALUE arg_args = rbs_node_list_to_ruby_array(ctx, node->args);
        VALUE arg_annotations = rbs_node_list_to_ruby_array(ctx, node->annotations);
        VALUE arg_comment = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->comment); // rbs_ast_comment

        // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
        // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
        VALUE h = ctx.reusable_kwargs_hash;
        rb_hash_clear(h);
        rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
        rb_hash_aset(h, ID2SYM(rb_intern("name")), arg_name);
        rb_hash_aset(h, ID2SYM(rb_intern("args")), arg_args);
        rb_hash_aset(h, ID2SYM(rb_intern("annotations")), arg_annotations);
        rb_hash_aset(h, ID2SYM(rb_intern("comment")), arg_comment);
        return CLASS_NEW_INSTANCE(RBS_AST_Members_Prepend, 1, &h);
    }
    case RBS_AST_MEMBERS_PRIVATE: {
        rbs_ast_members_private_t *node = (rbs_ast_members_private_t *) instance;

        // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
        VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);

        // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
        // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
        VALUE h = ctx.reusable_kwargs_hash;
        rb_hash_clear(h);
        rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
        return CLASS_NEW_INSTANCE(RBS_AST_Members_Private, 1, &h);
    }
    case RBS_AST_MEMBERS_PUBLIC: {
        rbs_ast_members_public_t *node = (rbs_ast_members_public_t *) instance;

        // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
        VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);

        // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
        // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
        VALUE h = ctx.reusable_kwargs_hash;
        rb_hash_clear(h);
        rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
        return CLASS_NEW_INSTANCE(RBS_AST_Members_Public, 1, &h);
    }
    case RBS_AST_RUBY_ANNOTATIONS_BLOCK_PARAM_TYPE_ANNOTATION: {
        rbs_ast_ruby_annotations_block_param_type_annotation_t *node = (rbs_ast_ruby_annotations_block_param_type_annotation_t *) instance;

        // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
        VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
        VALUE arg_prefix_location = rbs_location_range_to_ruby_location(ctx, node->prefix_location);
        VALUE arg_ampersand_location = rbs_location_range_to_ruby_location(ctx, node->ampersand_location);
        VALUE arg_name_location = rbs_location_range_to_ruby_location(ctx, node->name_location); // optional
        VALUE arg_colon_location = rbs_location_range_to_ruby_location(ctx, node->colon_location);
        VALUE arg_question_location = rbs_location_range_to_ruby_location(ctx, node->question_location); // optional
        VALUE arg_type_location = rbs_location_range_to_ruby_location(ctx, node->type_location);
        VALUE arg_type = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->type_);                    // rbs_node
        VALUE arg_comment_location = rbs_location_range_to_ruby_location(ctx, node->comment_location); // optional

        // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
        // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
        VALUE h = ctx.reusable_kwargs_hash;
        rb_hash_clear(h);
        rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
        rb_hash_aset(h, ID2SYM(rb_intern("prefix_location")), arg_prefix_location);
        rb_hash_aset(h, ID2SYM(rb_intern("ampersand_location")), arg_ampersand_location);
        rb_hash_aset(h, ID2SYM(rb_intern("name_location")), arg_name_location);
        rb_hash_aset(h, ID2SYM(rb_intern("colon_location")), arg_colon_location);
        rb_hash_aset(h, ID2SYM(rb_intern("question_location")), arg_question_location);
        rb_hash_aset(h, ID2SYM(rb_intern("type_location")), arg_type_location);
        rb_hash_aset(h, ID2SYM(rb_intern("type")), arg_type);
        rb_hash_aset(h, ID2SYM(rb_intern("comment_location")), arg_comment_location);
        return CLASS_NEW_INSTANCE(RBS_AST_Ruby_Annotations_BlockParamTypeAnnotation, 1, &h);
    }
    case RBS_AST_RUBY_ANNOTATIONS_CLASS_ALIAS_ANNOTATION: {
        rbs_ast_ruby_annotations_class_alias_annotation_t *node = (rbs_ast_ruby_annotations_class_alias_annotation_t *) instance;

        // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
        VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
        VALUE arg_prefix_location = rbs_location_range_to_ruby_location(ctx, node->prefix_location);
        VALUE arg_keyword_location = rbs_location_range_to_ruby_location(ctx, node->keyword_location);
        VALUE arg_type_name = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->type_name);               // rbs_type_name
        VALUE arg_type_name_location = rbs_location_range_to_ruby_location(ctx, node->type_name_location); // optional

        // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
        // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
        VALUE h = ctx.reusable_kwargs_hash;
        rb_hash_clear(h);
        rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
        rb_hash_aset(h, ID2SYM(rb_intern("prefix_location")), arg_prefix_location);
        rb_hash_aset(h, ID2SYM(rb_intern("keyword_location")), arg_keyword_location);
        rb_hash_aset(h, ID2SYM(rb_intern("type_name")), arg_type_name);
        rb_hash_aset(h, ID2SYM(rb_intern("type_name_location")), arg_type_name_location);
        return CLASS_NEW_INSTANCE(RBS_AST_Ruby_Annotations_ClassAliasAnnotation, 1, &h);
    }
    case RBS_AST_RUBY_ANNOTATIONS_COLON_METHOD_TYPE_ANNOTATION: {
        rbs_ast_ruby_annotations_colon_method_type_annotation_t *node = (rbs_ast_ruby_annotations_colon_method_type_annotation_t *) instance;

        // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
        VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
        VALUE arg_prefix_location = rbs_location_range_to_ruby_location(ctx, node->prefix_location);
        VALUE arg_annotations = rbs_node_list_to_ruby_array(ctx, node->annotations);
        VALUE arg_method_type = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->method_type); // rbs_node

        // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
        // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
        VALUE h = ctx.reusable_kwargs_hash;
        rb_hash_clear(h);
        rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
        rb_hash_aset(h, ID2SYM(rb_intern("prefix_location")), arg_prefix_location);
        rb_hash_aset(h, ID2SYM(rb_intern("annotations")), arg_annotations);
        rb_hash_aset(h, ID2SYM(rb_intern("method_type")), arg_method_type);
        return CLASS_NEW_INSTANCE(RBS_AST_Ruby_Annotations_ColonMethodTypeAnnotation, 1, &h);
    }
    case RBS_AST_RUBY_ANNOTATIONS_DOUBLE_SPLAT_PARAM_TYPE_ANNOTATION: {
        rbs_ast_ruby_annotations_double_splat_param_type_annotation_t *node = (rbs_ast_ruby_annotations_double_splat_param_type_annotation_t *) instance;

        // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
        VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
        VALUE arg_prefix_location = rbs_location_range_to_ruby_location(ctx, node->prefix_location);
        VALUE arg_star2_location = rbs_location_range_to_ruby_location(ctx, node->star2_location);
        VALUE arg_name_location = rbs_location_range_to_ruby_location(ctx, node->name_location); // optional
        VALUE arg_colon_location = rbs_location_range_to_ruby_location(ctx, node->colon_location);
        VALUE arg_param_type = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->param_type);         // rbs_node
        VALUE arg_comment_location = rbs_location_range_to_ruby_location(ctx, node->comment_location); // optional

        // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
        // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
        VALUE h = ctx.reusable_kwargs_hash;
        rb_hash_clear(h);
        rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
        rb_hash_aset(h, ID2SYM(rb_intern("prefix_location")), arg_prefix_location);
        rb_hash_aset(h, ID2SYM(rb_intern("star2_location")), arg_star2_location);
        rb_hash_aset(h, ID2SYM(rb_intern("name_location")), arg_name_location);
        rb_hash_aset(h, ID2SYM(rb_intern("colon_location")), arg_colon_location);
        rb_hash_aset(h, ID2SYM(rb_intern("param_type")), arg_param_type);
        rb_hash_aset(h, ID2SYM(rb_intern("comment_location")), arg_comment_location);
        return CLASS_NEW_INSTANCE(RBS_AST_Ruby_Annotations_DoubleSplatParamTypeAnnotation, 1, &h);
    }
    case RBS_AST_RUBY_ANNOTATIONS_INSTANCE_VARIABLE_ANNOTATION: {
        rbs_ast_ruby_annotations_instance_variable_annotation_t *node = (rbs_ast_ruby_annotations_instance_variable_annotation_t *) instance;

        // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
        VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
        VALUE arg_prefix_location = rbs_location_range_to_ruby_location(ctx, node->prefix_location);
        VALUE arg_ivar_name = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->ivar_name); // rbs_ast_symbol
        VALUE arg_ivar_name_location = rbs_location_range_to_ruby_location(ctx, node->ivar_name_location);
        VALUE arg_colon_location = rbs_location_range_to_ruby_location(ctx, node->colon_location);
        VALUE arg_type = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->type);                     // rbs_node
        VALUE arg_comment_location = rbs_location_range_to_ruby_location(ctx, node->comment_location); // optional

        // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
        // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
        VALUE h = ctx.reusable_kwargs_hash;
        rb_hash_clear(h);
        rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
        rb_hash_aset(h, ID2SYM(rb_intern("prefix_location")), arg_prefix_location);
        rb_hash_aset(h, ID2SYM(rb_intern("ivar_name")), arg_ivar_name);
        rb_hash_aset(h, ID2SYM(rb_intern("ivar_name_location")), arg_ivar_name_location);
        rb_hash_aset(h, ID2SYM(rb_intern("colon_location")), arg_colon_location);
        rb_hash_aset(h, ID2SYM(rb_intern("type")), arg_type);
        rb_hash_aset(h, ID2SYM(rb_intern("comment_location")), arg_comment_location);
        return CLASS_NEW_INSTANCE(RBS_AST_Ruby_Annotations_InstanceVariableAnnotation, 1, &h);
    }
    case RBS_AST_RUBY_ANNOTATIONS_METHOD_TYPES_ANNOTATION: {
        rbs_ast_ruby_annotations_method_types_annotation_t *node = (rbs_ast_ruby_annotations_method_types_annotation_t *) instance;

        // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
        VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
        VALUE arg_prefix_location = rbs_location_range_to_ruby_location(ctx, node->prefix_location);
        VALUE arg_overloads = rbs_node_list_to_ruby_array(ctx, node->overloads);
        VALUE arg_vertical_bar_locations = rbs_location_range_list_to_ruby_array(ctx, node->vertical_bar_locations);
        VALUE arg_dot3_location = rbs_location_range_to_ruby_location(ctx, node->dot3_location); // optional

        // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
        // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
        VALUE h = ctx.reusable_kwargs_hash;
        rb_hash_clear(h);
        rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
        rb_hash_aset(h, ID2SYM(rb_intern("prefix_location")), arg_prefix_location);
        rb_hash_aset(h, ID2SYM(rb_intern("overloads")), arg_overloads);
        rb_hash_aset(h, ID2SYM(rb_intern("vertical_bar_locations")), arg_vertical_bar_locations);
        rb_hash_aset(h, ID2SYM(rb_intern("dot3_location")), arg_dot3_location);
        return CLASS_NEW_INSTANCE(RBS_AST_Ruby_Annotations_MethodTypesAnnotation, 1, &h);
    }
    case RBS_AST_RUBY_ANNOTATIONS_MODULE_ALIAS_ANNOTATION: {
        rbs_ast_ruby_annotations_module_alias_annotation_t *node = (rbs_ast_ruby_annotations_module_alias_annotation_t *) instance;

        // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
        VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
        VALUE arg_prefix_location = rbs_location_range_to_ruby_location(ctx, node->prefix_location);
        VALUE arg_keyword_location = rbs_location_range_to_ruby_location(ctx, node->keyword_location);
        VALUE arg_type_name = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->type_name);               // rbs_type_name
        VALUE arg_type_name_location = rbs_location_range_to_ruby_location(ctx, node->type_name_location); // optional

        // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
        // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
        VALUE h = ctx.reusable_kwargs_hash;
        rb_hash_clear(h);
        rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
        rb_hash_aset(h, ID2SYM(rb_intern("prefix_location")), arg_prefix_location);
        rb_hash_aset(h, ID2SYM(rb_intern("keyword_location")), arg_keyword_location);
        rb_hash_aset(h, ID2SYM(rb_intern("type_name")), arg_type_name);
        rb_hash_aset(h, ID2SYM(rb_intern("type_name_location")), arg_type_name_location);
        return CLASS_NEW_INSTANCE(RBS_AST_Ruby_Annotations_ModuleAliasAnnotation, 1, &h);
    }
    case RBS_AST_RUBY_ANNOTATIONS_MODULE_SELF_ANNOTATION: {
        rbs_ast_ruby_annotations_module_self_annotation_t *node = (rbs_ast_ruby_annotations_module_self_annotation_t *) instance;

        // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
        VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
        VALUE arg_prefix_location = rbs_location_range_to_ruby_location(ctx, node->prefix_location);
        VALUE arg_keyword_location = rbs_location_range_to_ruby_location(ctx, node->keyword_location);
        VALUE arg_colon_location = rbs_location_range_to_ruby_location(ctx, node->colon_location);
        VALUE arg_name = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name); // rbs_type_name
        VALUE arg_args = rbs_node_list_to_ruby_array(ctx, node->args);
        VALUE arg_open_bracket_location = rbs_location_range_to_ruby_location(ctx, node->open_bracket_location);   // optional
        VALUE arg_close_bracket_location = rbs_location_range_to_ruby_location(ctx, node->close_bracket_location); // optional
        VALUE arg_args_comma_locations = rbs_location_range_list_to_ruby_array(ctx, node->args_comma_locations);
        VALUE arg_comment_location = rbs_location_range_to_ruby_location(ctx, node->comment_location); // optional

        // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
        // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
        VALUE h = ctx.reusable_kwargs_hash;
        rb_hash_clear(h);
        rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
        rb_hash_aset(h, ID2SYM(rb_intern("prefix_location")), arg_prefix_location);
        rb_hash_aset(h, ID2SYM(rb_intern("keyword_location")), arg_keyword_location);
        rb_hash_aset(h, ID2SYM(rb_intern("colon_location")), arg_colon_location);
        rb_hash_aset(h, ID2SYM(rb_intern("name")), arg_name);
        rb_hash_aset(h, ID2SYM(rb_intern("args")), arg_args);
        rb_hash_aset(h, ID2SYM(rb_intern("open_bracket_location")), arg_open_bracket_location);
        rb_hash_aset(h, ID2SYM(rb_intern("close_bracket_location")), arg_close_bracket_location);
        rb_hash_aset(h, ID2SYM(rb_intern("args_comma_locations")), arg_args_comma_locations);
        rb_hash_aset(h, ID2SYM(rb_intern("comment_location")), arg_comment_location);
        return CLASS_NEW_INSTANCE(RBS_AST_Ruby_Annotations_ModuleSelfAnnotation, 1, &h);
    }
    case RBS_AST_RUBY_ANNOTATIONS_NODE_TYPE_ASSERTION: {
        rbs_ast_ruby_annotations_node_type_assertion_t *node = (rbs_ast_ruby_annotations_node_type_assertion_t *) instance;

        // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
        VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
        VALUE arg_prefix_location = rbs_location_range_to_ruby_location(ctx, node->prefix_location);
        VALUE arg_type = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->type); // rbs_node

        // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
        // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
        VALUE h = ctx.reusable_kwargs_hash;
        rb_hash_clear(h);
        rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
        rb_hash_aset(h, ID2SYM(rb_intern("prefix_location")), arg_prefix_location);
        rb_hash_aset(h, ID2SYM(rb_intern("type")), arg_type);
        return CLASS_NEW_INSTANCE(RBS_AST_Ruby_Annotations_NodeTypeAssertion, 1, &h);
    }
    case RBS_AST_RUBY_ANNOTATIONS_PARAM_TYPE_ANNOTATION: {
        rbs_ast_ruby_annotations_param_type_annotation_t *node = (rbs_ast_ruby_annotations_param_type_annotation_t *) instance;

        // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
        VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
        VALUE arg_prefix_location = rbs_location_range_to_ruby_location(ctx, node->prefix_location);
        VALUE arg_name_location = rbs_location_range_to_ruby_location(ctx, node->name_location);
        VALUE arg_colon_location = rbs_location_range_to_ruby_location(ctx, node->colon_location);
        VALUE arg_param_type = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->param_type);         // rbs_node
        VALUE arg_comment_location = rbs_location_range_to_ruby_location(ctx, node->comment_location); // optional

        // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
        // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
        VALUE h = ctx.reusable_kwargs_hash;
        rb_hash_clear(h);
        rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
        rb_hash_aset(h, ID2SYM(rb_intern("prefix_location")), arg_prefix_location);
        rb_hash_aset(h, ID2SYM(rb_intern("name_location")), arg_name_location);
        rb_hash_aset(h, ID2SYM(rb_intern("colon_location")), arg_colon_location);
        rb_hash_aset(h, ID2SYM(rb_intern("param_type")), arg_param_type);
        rb_hash_aset(h, ID2SYM(rb_intern("comment_location")), arg_comment_location);
        return CLASS_NEW_INSTANCE(RBS_AST_Ruby_Annotations_ParamTypeAnnotation, 1, &h);
    }
    case RBS_AST_RUBY_ANNOTATIONS_RETURN_TYPE_ANNOTATION: {
        rbs_ast_ruby_annotations_return_type_annotation_t *node = (rbs_ast_ruby_annotations_return_type_annotation_t *) instance;

        // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
        VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
        VALUE arg_prefix_location = rbs_location_range_to_ruby_location(ctx, node->prefix_location);
        VALUE arg_return_location = rbs_location_range_to_ruby_location(ctx, node->return_location);
        VALUE arg_colon_location = rbs_location_range_to_ruby_location(ctx, node->colon_location);
        VALUE arg_return_type = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->return_type);       // rbs_node
        VALUE arg_comment_location = rbs_location_range_to_ruby_location(ctx, node->comment_location); // optional

        // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
        // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
        VALUE h = ctx.reusable_kwargs_hash;
        rb_hash_clear(h);
        rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
        rb_hash_aset(h, ID2SYM(rb_intern("prefix_location")), arg_prefix_location);
        rb_hash_aset(h, ID2SYM(rb_intern("return_location")), arg_return_location);
        rb_hash_aset(h, ID2SYM(rb_intern("colon_location")), arg_colon_location);
        rb_hash_aset(h, ID2SYM(rb_intern("return_type")), arg_return_type);
        rb_hash_aset(h, ID2SYM(rb_intern("comment_location")), arg_comment_location);
        return CLASS_NEW_INSTANCE(RBS_AST_Ruby_Annotations_ReturnTypeAnnotation, 1, &h);
    }
    case RBS_AST_RUBY_ANNOTATIONS_SKIP_ANNOTATION: {
        rbs_ast_ruby_annotations_skip_annotation_t *node = (rbs_ast_ruby_annotations_skip_annotation_t *) instance;

        // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
        VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
        VALUE arg_prefix_location = rbs_location_range_to_ruby_location(ctx, node->prefix_location);
        VALUE arg_skip_location = rbs_location_range_to_ruby_location(ctx, node->skip_location);
        VALUE arg_comment_location = rbs_location_range_to_ruby_location(ctx, node->comment_location); // optional

        // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
        // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
        VALUE h = ctx.reusable_kwargs_hash;
        rb_hash_clear(h);
        rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
        rb_hash_aset(h, ID2SYM(rb_intern("prefix_location")), arg_prefix_location);
        rb_hash_aset(h, ID2SYM(rb_intern("skip_location")), arg_skip_location);
        rb_hash_aset(h, ID2SYM(rb_intern("comment_location")), arg_comment_location);
        return CLASS_NEW_INSTANCE(RBS_AST_Ruby_Annotations_SkipAnnotation, 1, &h);
    }
    case RBS_AST_RUBY_ANNOTATIONS_SPLAT_PARAM_TYPE_ANNOTATION: {
        rbs_ast_ruby_annotations_splat_param_type_annotation_t *node = (rbs_ast_ruby_annotations_splat_param_type_annotation_t *) instance;

        // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
        VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
        VALUE arg_prefix_location = rbs_location_range_to_ruby_location(ctx, node->prefix_location);
        VALUE arg_star_location = rbs_location_range_to_ruby_location(ctx, node->star_location);
        VALUE arg_name_location = rbs_location_range_to_ruby_location(ctx, node->name_location); // optional
        VALUE arg_colon_location = rbs_location_range_to_ruby_location(ctx, node->colon_location);
        VALUE arg_param_type = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->param_type);         // rbs_node
        VALUE arg_comment_location = rbs_location_range_to_ruby_location(ctx, node->comment_location); // optional

        // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
        // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
        VALUE h = ctx.reusable_kwargs_hash;
        rb_hash_clear(h);
        rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
        rb_hash_aset(h, ID2SYM(rb_intern("prefix_location")), arg_prefix_location);
        rb_hash_aset(h, ID2SYM(rb_intern("star_location")), arg_star_location);
        rb_hash_aset(h, ID2SYM(rb_intern("name_location")), arg_name_location);
        rb_hash_aset(h, ID2SYM(rb_intern("colon_location")), arg_colon_location);
        rb_hash_aset(h, ID2SYM(rb_intern("param_type")), arg_param_type);
        rb_hash_aset(h, ID2SYM(rb_intern("comment_location")), arg_comment_location);
        return CLASS_NEW_INSTANCE(RBS_AST_Ruby_Annotations_SplatParamTypeAnnotation, 1, &h);
    }
    case RBS_AST_RUBY_ANNOTATIONS_TYPE_APPLICATION_ANNOTATION: {
        rbs_ast_ruby_annotations_type_application_annotation_t *node = (rbs_ast_ruby_annotations_type_application_annotation_t *) instance;

        // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
        VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
        VALUE arg_prefix_location = rbs_location_range_to_ruby_location(ctx, node->prefix_location);
        VALUE arg_type_args = rbs_node_list_to_ruby_array(ctx, node->type_args);
        VALUE arg_close_bracket_location = rbs_location_range_to_ruby_location(ctx, node->close_bracket_location);
        VALUE arg_comma_locations = rbs_location_range_list_to_ruby_array(ctx, node->comma_locations);

        // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
        // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
        VALUE h = ctx.reusable_kwargs_hash;
        rb_hash_clear(h);
        rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
        rb_hash_aset(h, ID2SYM(rb_intern("prefix_location")), arg_prefix_location);
        rb_hash_aset(h, ID2SYM(rb_intern("type_args")), arg_type_args);
        rb_hash_aset(h, ID2SYM(rb_intern("close_bracket_location")), arg_close_bracket_location);
        rb_hash_aset(h, ID2SYM(rb_intern("comma_locations")), arg_comma_locations);
        return CLASS_NEW_INSTANCE(RBS_AST_Ruby_Annotations_TypeApplicationAnnotation, 1, &h);
    }
    case RBS_AST_STRING: {
        rbs_ast_string_t *string_node = (rbs_ast_string_t *) instance;
        rbs_string_t s = string_node->string;

        return rb_enc_str_new(s.start, rbs_string_len(s), rb_utf8_encoding());
    }
    case RBS_AST_TYPE_PARAM: {
        rbs_ast_type_param_t *node = (rbs_ast_type_param_t *) instance;

        // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
        VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
        rbs_loc *loc = rbs_check_location(arg_location);
        {
            rbs_loc_legacy_alloc_children(loc, 6);
            rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_char, .end = node->name_range.end_char });
            rbs_loc_legacy_add_optional_child(loc, rb_intern("variance"), (rbs_loc_range) { .start = node->variance_range.start_char, .end = node->variance_range.end_char });
            rbs_loc_legacy_add_optional_child(loc, rb_intern("unchecked"), (rbs_loc_range) { .start = node->unchecked_range.start_char, .end = node->unchecked_range.end_char });
            rbs_loc_legacy_add_optional_child(loc, rb_intern("upper_bound"), (rbs_loc_range) { .start = node->upper_bound_range.start_char, .end = node->upper_bound_range.end_char });
            rbs_loc_legacy_add_optional_child(loc, rb_intern("lower_bound"), (rbs_loc_range) { .start = node->lower_bound_range.start_char, .end = node->lower_bound_range.end_char });
            rbs_loc_legacy_add_optional_child(loc, rb_intern("default"), (rbs_loc_range) { .start = node->default_range.start_char, .end = node->default_range.end_char });
        }
        VALUE arg_name = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name);                 // rbs_ast_symbol
        VALUE arg_variance = rbs_type_param_variance_to_ruby(node->variance);                      // type_param_variance
        VALUE arg_upper_bound = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->upper_bound);   // rbs_node
        VALUE arg_lower_bound = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->lower_bound);   // rbs_node
        VALUE arg_default_type = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->default_type); // rbs_node
        VALUE arg_unchecked = node->unchecked ? Qtrue : Qfalse;

        // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
        // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
        VALUE h = ctx.reusable_kwargs_hash;
        rb_hash_clear(h);
        rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
        rb_hash_aset(h, ID2SYM(rb_intern("name")), arg_name);
        rb_hash_aset(h, ID2SYM(rb_intern("variance")), arg_variance);
        rb_hash_aset(h, ID2SYM(rb_intern("upper_bound")), arg_upper_bound);
        rb_hash_aset(h, ID2SYM(rb_intern("lower_bound")), arg_lower_bound);
        rb_hash_aset(h, ID2SYM(rb_intern("default_type")), arg_default_type);
        rb_hash_aset(h, ID2SYM(rb_intern("unchecked")), arg_unchecked);
        return CLASS_NEW_INSTANCE(RBS_AST_TypeParam, 1, &h);
    }
    case RBS_METHOD_TYPE: {
        rbs_method_type_t *node = (rbs_method_type_t *) instance;

        // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
        VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
        rbs_loc *loc = rbs_check_location(arg_location);
        {
            rbs_loc_legacy_alloc_children(loc, 2);
            rbs_loc_legacy_add_required_child(loc, rb_intern("type"), (rbs_loc_range) { .start = node->type_range.start_char, .end = node->type_range.end_char });
            rbs_loc_legacy_add_optional_child(loc, rb_intern("type_params"), (rbs_loc_range) { .start = node->type_params_range.start_char, .end = node->type_params_range.end_char });
        }
        VALUE arg_type_params = rbs_node_list_to_ruby_array(ctx, node->type_params);
        VALUE arg_type = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->type);   // rbs_node
        VALUE arg_block = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->block); // rbs_types_block

        rb_funcall(
            RBS_AST_TypeParam,
            rb_intern("resolve_variables"),
            1,
            arg_type_params
        );
        // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
        // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
        VALUE h = ctx.reusable_kwargs_hash;
        rb_hash_clear(h);
        rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
        rb_hash_aset(h, ID2SYM(rb_intern("type_params")), arg_type_params);
        rb_hash_aset(h, ID2SYM(rb_intern("type")), arg_type);
        rb_hash_aset(h, ID2SYM(rb_intern("block")), arg_block);
        return CLASS_NEW_INSTANCE(RBS_MethodType, 1, &h);
    }
    case RBS_NAMESPACE: {
        return rbs_intern_namespace(ctx, (rbs_namespace_t *) instance);
    }
    case RBS_SIGNATURE: {
        rbs_signature_t *signature = (rbs_signature_t *) instance;

        VALUE array = rb_ary_new();
        rb_ary_push(array, rbs_node_list_to_ruby_array(ctx, signature->directives));
        rb_ary_push(array, rbs_node_list_to_ruby_array(ctx, signature->declarations));
        return array;
    }
    case RBS_TYPE_NAME: {
        rbs_type_name_t *node = (rbs_type_name_t *) instance;
        VALUE ns = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->rbs_namespace);
        VALUE name = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name);
        return rbs_intern_type_name(ns, name);
    }
    case RBS_TYPES_ALIAS: {
        rbs_types_alias_t *node = (rbs_types_alias_t *) instance;

        // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
        VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
        rbs_loc *loc = rbs_check_location(arg_location);
        {
            rbs_loc_legacy_alloc_children(loc, 2);
            rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_char, .end = node->name_range.end_char });
            rbs_loc_legacy_add_optional_child(loc, rb_intern("args"), (rbs_loc_range) { .start = node->args_range.start_char, .end = node->args_range.end_char });
        }
        VALUE arg_name = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name); // rbs_type_name
        VALUE arg_args = rbs_node_list_to_ruby_array(ctx, node->args);

        // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
        // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
        VALUE h = ctx.reusable_kwargs_hash;
        rb_hash_clear(h);
        rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
        rb_hash_aset(h, ID2SYM(rb_intern("name")), arg_name);
        rb_hash_aset(h, ID2SYM(rb_intern("args")), arg_args);
        return CLASS_NEW_INSTANCE(RBS_Types_Alias, 1, &h);
    }
    case RBS_TYPES_BASES_ANY: {
        rbs_types_bases_any_t *node = (rbs_types_bases_any_t *) instance;

        // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
        VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
        VALUE arg_todo = node->todo ? Qtrue : Qfalse;

        // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
        // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
        VALUE h = ctx.reusable_kwargs_hash;
        rb_hash_clear(h);
        rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
        rb_hash_aset(h, ID2SYM(rb_intern("todo")), arg_todo);
        return CLASS_NEW_INSTANCE(RBS_Types_Bases_Any, 1, &h);
    }
    case RBS_TYPES_BASES_BOOL: {
        rbs_types_bases_bool_t *node = (rbs_types_bases_bool_t *) instance;

        // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
        VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);

        // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
        // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
        VALUE h = ctx.reusable_kwargs_hash;
        rb_hash_clear(h);
        rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
        return CLASS_NEW_INSTANCE(RBS_Types_Bases_Bool, 1, &h);
    }
    case RBS_TYPES_BASES_BOTTOM: {
        rbs_types_bases_bottom_t *node = (rbs_types_bases_bottom_t *) instance;

        // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
        VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);

        // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
        // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
        VALUE h = ctx.reusable_kwargs_hash;
        rb_hash_clear(h);
        rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
        return CLASS_NEW_INSTANCE(RBS_Types_Bases_Bottom, 1, &h);
    }
    case RBS_TYPES_BASES_CLASS: {
        rbs_types_bases_class_t *node = (rbs_types_bases_class_t *) instance;

        // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
        VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);

        // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
        // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
        VALUE h = ctx.reusable_kwargs_hash;
        rb_hash_clear(h);
        rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
        return CLASS_NEW_INSTANCE(RBS_Types_Bases_Class, 1, &h);
    }
    case RBS_TYPES_BASES_INSTANCE: {
        rbs_types_bases_instance_t *node = (rbs_types_bases_instance_t *) instance;

        // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
        VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);

        // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
        // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
        VALUE h = ctx.reusable_kwargs_hash;
        rb_hash_clear(h);
        rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
        return CLASS_NEW_INSTANCE(RBS_Types_Bases_Instance, 1, &h);
    }
    case RBS_TYPES_BASES_NIL: {
        rbs_types_bases_nil_t *node = (rbs_types_bases_nil_t *) instance;

        // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
        VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);

        // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
        // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
        VALUE h = ctx.reusable_kwargs_hash;
        rb_hash_clear(h);
        rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
        return CLASS_NEW_INSTANCE(RBS_Types_Bases_Nil, 1, &h);
    }
    case RBS_TYPES_BASES_SELF: {
        rbs_types_bases_self_t *node = (rbs_types_bases_self_t *) instance;

        // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
        VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);

        // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
        // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
        VALUE h = ctx.reusable_kwargs_hash;
        rb_hash_clear(h);
        rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
        return CLASS_NEW_INSTANCE(RBS_Types_Bases_Self, 1, &h);
    }
    case RBS_TYPES_BASES_TOP: {
        rbs_types_bases_top_t *node = (rbs_types_bases_top_t *) instance;

        // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
        VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);

        // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
        // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
        VALUE h = ctx.reusable_kwargs_hash;
        rb_hash_clear(h);
        rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
        return CLASS_NEW_INSTANCE(RBS_Types_Bases_Top, 1, &h);
    }
    case RBS_TYPES_BASES_VOID: {
        rbs_types_bases_void_t *node = (rbs_types_bases_void_t *) instance;

        // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
        VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);

        // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
        // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
        VALUE h = ctx.reusable_kwargs_hash;
        rb_hash_clear(h);
        rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
        return CLASS_NEW_INSTANCE(RBS_Types_Bases_Void, 1, &h);
    }
    case RBS_TYPES_BLOCK: {
        rbs_types_block_t *node = (rbs_types_block_t *) instance;

        // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
        VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
        VALUE arg_type = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->type); // rbs_node
        VALUE arg_required = node->required ? Qtrue : Qfalse;
        VALUE arg_self_type = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->self_type); // rbs_node

        // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
        // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
        VALUE h = ctx.reusable_kwargs_hash;
        rb_hash_clear(h);
        rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
        rb_hash_aset(h, ID2SYM(rb_intern("type")), arg_type);
        rb_hash_aset(h, ID2SYM(rb_intern("required")), arg_required);
        rb_hash_aset(h, ID2SYM(rb_intern("self_type")), arg_self_type);
        return CLASS_NEW_INSTANCE(RBS_Types_Block, 1, &h);
    }
    case RBS_TYPES_CLASS_INSTANCE: {
        rbs_types_class_instance_t *node = (rbs_types_class_instance_t *) instance;

        // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
        VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
        rbs_loc *loc = rbs_check_location(arg_location);
        {
            rbs_loc_legacy_alloc_children(loc, 2);
            rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_char, .end = node->name_range.end_char });
            rbs_loc_legacy_add_optional_child(loc, rb_intern("args"), (rbs_loc_range) { .start = node->args_range.start_char, .end = node->args_range.end_char });
        }
        VALUE arg_name = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name); // rbs_type_name
        VALUE arg_args = rbs_node_list_to_ruby_array(ctx, node->args);

        // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
        // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
        VALUE h = ctx.reusable_kwargs_hash;
        rb_hash_clear(h);
        rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
        rb_hash_aset(h, ID2SYM(rb_intern("name")), arg_name);
        rb_hash_aset(h, ID2SYM(rb_intern("args")), arg_args);
        return CLASS_NEW_INSTANCE(RBS_Types_ClassInstance, 1, &h);
    }
    case RBS_TYPES_CLASS_SINGLETON: {
        rbs_types_class_singleton_t *node = (rbs_types_class_singleton_t *) instance;

        // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
        VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
        rbs_loc *loc = rbs_check_location(arg_location);
        {
            rbs_loc_legacy_alloc_children(loc, 2);
            rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_char, .end = node->name_range.end_char });
            rbs_loc_legacy_add_optional_child(loc, rb_intern("args"), (rbs_loc_range) { .start = node->args_range.start_char, .end = node->args_range.end_char });
        }
        VALUE arg_name = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name); // rbs_type_name
        VALUE arg_args = rbs_node_list_to_ruby_array(ctx, node->args);

        // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
        // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
        VALUE h = ctx.reusable_kwargs_hash;
        rb_hash_clear(h);
        rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
        rb_hash_aset(h, ID2SYM(rb_intern("name")), arg_name);
        rb_hash_aset(h, ID2SYM(rb_intern("args")), arg_args);
        return CLASS_NEW_INSTANCE(RBS_Types_ClassSingleton, 1, &h);
    }
    case RBS_TYPES_FUNCTION: {
        rbs_types_function_t *node = (rbs_types_function_t *) instance;

        // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
        VALUE arg_required_positionals = rbs_node_list_to_ruby_array(ctx, node->required_positionals);
        VALUE arg_optional_positionals = rbs_node_list_to_ruby_array(ctx, node->optional_positionals);
        VALUE arg_rest_positionals = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->rest_positionals); // rbs_node
        VALUE arg_trailing_positionals = rbs_node_list_to_ruby_array(ctx, node->trailing_positionals);
        VALUE arg_required_keywords = rbs_hash_to_ruby_hash(ctx, node->required_keywords);
        VALUE arg_optional_keywords = rbs_hash_to_ruby_hash(ctx, node->optional_keywords);
        VALUE arg_rest_keywords = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->rest_keywords); // rbs_node
        VALUE arg_forwarding = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->forwarding);       // rbs_node
        VALUE arg_return_type = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->return_type);     // rbs_node

        // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
        // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
        VALUE h = ctx.reusable_kwargs_hash;
        rb_hash_clear(h);
        rb_hash_aset(h, ID2SYM(rb_intern("required_positionals")), arg_required_positionals);
        rb_hash_aset(h, ID2SYM(rb_intern("optional_positionals")), arg_optional_positionals);
        rb_hash_aset(h, ID2SYM(rb_intern("rest_positionals")), arg_rest_positionals);
        rb_hash_aset(h, ID2SYM(rb_intern("trailing_positionals")), arg_trailing_positionals);
        rb_hash_aset(h, ID2SYM(rb_intern("required_keywords")), arg_required_keywords);
        rb_hash_aset(h, ID2SYM(rb_intern("optional_keywords")), arg_optional_keywords);
        rb_hash_aset(h, ID2SYM(rb_intern("rest_keywords")), arg_rest_keywords);
        rb_hash_aset(h, ID2SYM(rb_intern("forwarding")), arg_forwarding);
        rb_hash_aset(h, ID2SYM(rb_intern("return_type")), arg_return_type);
        return CLASS_NEW_INSTANCE(RBS_Types_Function, 1, &h);
    }
    case RBS_TYPES_FUNCTION_FORWARDING_PARAM: {
        rbs_types_function_forwarding_param_t *node = (rbs_types_function_forwarding_param_t *) instance;

        // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
        VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);

        // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
        // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
        VALUE h = ctx.reusable_kwargs_hash;
        rb_hash_clear(h);
        rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
        return CLASS_NEW_INSTANCE(RBS_Types_Function_ForwardingParam, 1, &h);
    }
    case RBS_TYPES_FUNCTION_PARAM: {
        rbs_types_function_param_t *node = (rbs_types_function_param_t *) instance;

        // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
        VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
        rbs_loc *loc = rbs_check_location(arg_location);
        {
            rbs_loc_legacy_alloc_children(loc, 1);
            rbs_loc_legacy_add_optional_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_char, .end = node->name_range.end_char });
        }
        VALUE arg_type = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->type); // rbs_node
        VALUE arg_name = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name); // rbs_ast_symbol

        // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
        // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
        VALUE h = ctx.reusable_kwargs_hash;
        rb_hash_clear(h);
        rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
        rb_hash_aset(h, ID2SYM(rb_intern("type")), arg_type);
        rb_hash_aset(h, ID2SYM(rb_intern("name")), arg_name);
        return CLASS_NEW_INSTANCE(RBS_Types_Function_Param, 1, &h);
    }
    case RBS_TYPES_INTERFACE: {
        rbs_types_interface_t *node = (rbs_types_interface_t *) instance;

        // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
        VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
        rbs_loc *loc = rbs_check_location(arg_location);
        {
            rbs_loc_legacy_alloc_children(loc, 2);
            rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_char, .end = node->name_range.end_char });
            rbs_loc_legacy_add_optional_child(loc, rb_intern("args"), (rbs_loc_range) { .start = node->args_range.start_char, .end = node->args_range.end_char });
        }
        VALUE arg_name = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name); // rbs_type_name
        VALUE arg_args = rbs_node_list_to_ruby_array(ctx, node->args);

        // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
        // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
        VALUE h = ctx.reusable_kwargs_hash;
        rb_hash_clear(h);
        rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
        rb_hash_aset(h, ID2SYM(rb_intern("name")), arg_name);
        rb_hash_aset(h, ID2SYM(rb_intern("args")), arg_args);
        return CLASS_NEW_INSTANCE(RBS_Types_Interface, 1, &h);
    }
    case RBS_TYPES_INTERSECTION: {
        rbs_types_intersection_t *node = (rbs_types_intersection_t *) instance;

        // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
        VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
        VALUE arg_types = rbs_node_list_to_ruby_array(ctx, node->types);

        // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
        // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
        VALUE h = ctx.reusable_kwargs_hash;
        rb_hash_clear(h);
        rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
        rb_hash_aset(h, ID2SYM(rb_intern("types")), arg_types);
        return CLASS_NEW_INSTANCE(RBS_Types_Intersection, 1, &h);
    }
    case RBS_TYPES_LITERAL: {
        rbs_types_literal_t *node = (rbs_types_literal_t *) instance;

        // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
        VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
        VALUE arg_literal = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->literal); // rbs_node

        // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
        // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
        VALUE h = ctx.reusable_kwargs_hash;
        rb_hash_clear(h);
        rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
        rb_hash_aset(h, ID2SYM(rb_intern("literal")), arg_literal);
        return CLASS_NEW_INSTANCE(RBS_Types_Literal, 1, &h);
    }
    case RBS_TYPES_OPTIONAL: {
        rbs_types_optional_t *node = (rbs_types_optional_t *) instance;

        // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
        VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
        VALUE arg_type = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->type); // rbs_node

        // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
        // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
        VALUE h = ctx.reusable_kwargs_hash;
        rb_hash_clear(h);
        rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
        rb_hash_aset(h, ID2SYM(rb_intern("type")), arg_type);
        return CLASS_NEW_INSTANCE(RBS_Types_Optional, 1, &h);
    }
    case RBS_TYPES_PROC: {
        rbs_types_proc_t *node = (rbs_types_proc_t *) instance;

        // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
        VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
        VALUE arg_type = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->type);           // rbs_node
        VALUE arg_block = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->block);         // rbs_types_block
        VALUE arg_self_type = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->self_type); // rbs_node

        // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
        // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
        VALUE h = ctx.reusable_kwargs_hash;
        rb_hash_clear(h);
        rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
        rb_hash_aset(h, ID2SYM(rb_intern("type")), arg_type);
        rb_hash_aset(h, ID2SYM(rb_intern("block")), arg_block);
        rb_hash_aset(h, ID2SYM(rb_intern("self_type")), arg_self_type);
        return CLASS_NEW_INSTANCE(RBS_Types_Proc, 1, &h);
    }
    case RBS_TYPES_RECORD: {
        rbs_types_record_t *node = (rbs_types_record_t *) instance;

        // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
        VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
        VALUE arg_all_fields = rbs_hash_to_ruby_hash(ctx, node->all_fields);

        // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
        // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
        VALUE h = ctx.reusable_kwargs_hash;
        rb_hash_clear(h);
        rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
        rb_hash_aset(h, ID2SYM(rb_intern("all_fields")), arg_all_fields);
        return CLASS_NEW_INSTANCE(RBS_Types_Record, 1, &h);
    }
    case RBS_TYPES_RECORD_FIELD_TYPE: {
        rbs_types_record_field_type_t *record_fieldtype = (rbs_types_record_field_type_t *) instance;

        VALUE array = rb_ary_new();
        rb_ary_push(array, rbs_struct_to_ruby_value(ctx, record_fieldtype->type));
        rb_ary_push(array, record_fieldtype->required ? Qtrue : Qfalse);
        return array;
    }
    case RBS_TYPES_TUPLE: {
        rbs_types_tuple_t *node = (rbs_types_tuple_t *) instance;

        // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
        VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
        VALUE arg_types = rbs_node_list_to_ruby_array(ctx, node->types);

        // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
        // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
        VALUE h = ctx.reusable_kwargs_hash;
        rb_hash_clear(h);
        rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
        rb_hash_aset(h, ID2SYM(rb_intern("types")), arg_types);
        return CLASS_NEW_INSTANCE(RBS_Types_Tuple, 1, &h);
    }
    case RBS_TYPES_UNION: {
        rbs_types_union_t *node = (rbs_types_union_t *) instance;

        // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
        VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
        VALUE arg_types = rbs_node_list_to_ruby_array(ctx, node->types);

        // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
        // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
        VALUE h = ctx.reusable_kwargs_hash;
        rb_hash_clear(h);
        rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
        rb_hash_aset(h, ID2SYM(rb_intern("types")), arg_types);
        return CLASS_NEW_INSTANCE(RBS_Types_Union, 1, &h);
    }
    case RBS_TYPES_UNTYPED_FUNCTION: {
        rbs_types_untyped_function_t *node = (rbs_types_untyped_function_t *) instance;

        // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
        VALUE arg_return_type = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->return_type); // rbs_node

        // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
        // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
        VALUE h = ctx.reusable_kwargs_hash;
        rb_hash_clear(h);
        rb_hash_aset(h, ID2SYM(rb_intern("return_type")), arg_return_type);
        return CLASS_NEW_INSTANCE(RBS_Types_UntypedFunction, 1, &h);
    }
    case RBS_TYPES_VARIABLE: {
        rbs_types_variable_t *node = (rbs_types_variable_t *) instance;

        // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
        VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
        VALUE arg_name = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name); // rbs_ast_symbol

        // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
        // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
        VALUE h = ctx.reusable_kwargs_hash;
        rb_hash_clear(h);
        rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
        rb_hash_aset(h, ID2SYM(rb_intern("name")), arg_name);
        return CLASS_NEW_INSTANCE(RBS_Types_Variable, 1, &h);
    }
    case RBS_AST_SYMBOL: {
        rbs_constant_t *constant = rbs_constant_pool_id_to_constant(ctx.constant_pool, ((rbs_ast_symbol_t *) instance)->constant_id);
        assert(constant != NULL && "constant is NULL");
        assert(constant->start != NULL && "constant->start is NULL");

        return ID2SYM(rb_intern3((const char *) constant->start, constant->length, ctx.encoding));
    }
    }

    rb_raise(rb_eRuntimeError, "Unknown node type: %d", instance->type);
}
