/******************************************************************************/
/* This file is generated by the templates/template.rb script and should not  */
/* be modified manually. See                                                  */
/* templates/src/prettyprint.c.erb                                            */
/* if you are looking to modify the                                           */
/* template                                                                   */
/******************************************************************************/
#include "prism/prettyprint.h"

static void
prettyprint_source(pm_buffer_t *output_buffer, const uint8_t *source, size_t length) {
    for (size_t index = 0; index < length; index++) {
        const uint8_t byte = source[index];

        if ((byte <= 0x06) || (byte >= 0x0E && byte <= 0x1F) || (byte >= 0x7F)) {
            pm_buffer_append_format(output_buffer, "\\x%02X", byte);
        } else {
            switch (byte) {
                case '\a': pm_buffer_append_string(output_buffer, "\\a", 2); break;
                case '\b': pm_buffer_append_string(output_buffer, "\\b", 2); break;
                case '\t': pm_buffer_append_string(output_buffer, "\\t", 2); break;
                case '\n': pm_buffer_append_string(output_buffer, "\\n", 2); break;
                case '\v': pm_buffer_append_string(output_buffer, "\\v", 2); break;
                case '\f': pm_buffer_append_string(output_buffer, "\\f", 2); break;
                case '\r': pm_buffer_append_string(output_buffer, "\\r", 2); break;
                case '"': pm_buffer_append_string(output_buffer, "\\\"", 2); break;
                case '#': {
                    if (index + 1 < length) {
                        const uint8_t next_byte = source[index + 1];
                        if (next_byte == '{' || next_byte == '@' || next_byte == '$') {
                            pm_buffer_append_byte(output_buffer, '\\');
                        }
                    }

                    pm_buffer_append_byte(output_buffer, '#');
                    break;
                }
                case '\\': pm_buffer_append_string(output_buffer, "\\\\", 2); break;
                default: pm_buffer_append_byte(output_buffer, byte); break;
            }
        }
    }
}

static inline void
prettyprint_location(pm_buffer_t *output_buffer, const pm_parser_t *parser, const pm_location_t *location) {
    pm_line_column_t start = pm_newline_list_line_column(&parser->newline_list, location->start);
    pm_line_column_t end = pm_newline_list_line_column(&parser->newline_list, location->end);
    pm_buffer_append_format(output_buffer, "(%lu,%lu)-(%lu,%lu)", (unsigned long) (start.line + 1), (unsigned long) start.column, (unsigned long) (end.line + 1), (unsigned long) end.column);
}

static inline void
prettyprint_constant(pm_buffer_t *output_buffer, const pm_parser_t *parser, const pm_constant_id_t constant_id) {
    pm_constant_t *constant = pm_constant_pool_id_to_constant(&parser->constant_pool, constant_id);
    pm_buffer_append_format(output_buffer, ":%.*s", (int) constant->length, constant->start);
}

static void
prettyprint_node(pm_buffer_t *output_buffer, const pm_parser_t *parser, const pm_node_t *node, pm_buffer_t *prefix_buffer) {
    switch (PM_NODE_TYPE(node)) {
        case PM_SCOPE_NODE:
            // We do not need to print a ScopeNode as it's not part of the AST.
            return;
        case PM_ALIAS_GLOBAL_VARIABLE_NODE: {
            pm_alias_global_variable_node_t *cast = (pm_alias_global_variable_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ AliasGlobalVariableNode (location: ", 37);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // new_name
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 new_name:", 19);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->new_name, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            // old_name
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 old_name:", 19);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->old_name, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            // keyword_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 keyword_loc:", 22);
                pm_location_t *location = &cast->keyword_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            break;
        }
        case PM_ALIAS_METHOD_NODE: {
            pm_alias_method_node_t *cast = (pm_alias_method_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ AliasMethodNode (location: ", 29);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // new_name
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 new_name:", 19);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->new_name, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            // old_name
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 old_name:", 19);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->old_name, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            // keyword_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 keyword_loc:", 22);
                pm_location_t *location = &cast->keyword_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            break;
        }
        case PM_ALTERNATION_PATTERN_NODE: {
            pm_alternation_pattern_node_t *cast = (pm_alternation_pattern_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ AlternationPatternNode (location: ", 36);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // left
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 left:", 15);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->left, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            // right
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 right:", 16);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->right, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            // operator_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 operator_loc:", 23);
                pm_location_t *location = &cast->operator_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            break;
        }
        case PM_AND_NODE: {
            pm_and_node_t *cast = (pm_and_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ AndNode (location: ", 21);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // left
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 left:", 15);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->left, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            // right
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 right:", 16);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->right, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            // operator_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 operator_loc:", 23);
                pm_location_t *location = &cast->operator_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            break;
        }
        case PM_ARGUMENTS_NODE: {
            pm_arguments_node_t *cast = (pm_arguments_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ ArgumentsNode (location: ", 27);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // flags
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 flags:", 16);
                bool found = false;
                if (cast->base.flags & PM_ARGUMENTS_NODE_FLAGS_CONTAINS_KEYWORD_SPLAT) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " contains_keyword_splat", 23);
                    found = true;
                }
                if (!found) pm_buffer_append_string(output_buffer, " \xe2\x88\x85", 4);
                pm_buffer_append_byte(output_buffer, '\n');
            }

            // arguments
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 arguments:", 20);
                pm_buffer_append_format(output_buffer, " (length: %lu)\n", (unsigned long) (cast->arguments.size));

                size_t last_index = cast->arguments.size;
                for (uint32_t index = 0; index < last_index; index++) {
                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "    ", 4);
                    pm_buffer_concat(output_buffer, prefix_buffer);

                    if (index == last_index - 1) {
                        pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 ", 10);
                        pm_buffer_append_string(prefix_buffer, "    ", 4);
                    } else {
                        pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 ", 10);
                        pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    }

                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->arguments.nodes[index], prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            break;
        }
        case PM_ARRAY_NODE: {
            pm_array_node_t *cast = (pm_array_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ ArrayNode (location: ", 23);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // flags
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 flags:", 16);
                bool found = false;
                if (cast->base.flags & PM_ARRAY_NODE_FLAGS_CONTAINS_SPLAT) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " contains_splat", 15);
                    found = true;
                }
                if (!found) pm_buffer_append_string(output_buffer, " \xe2\x88\x85", 4);
                pm_buffer_append_byte(output_buffer, '\n');
            }

            // elements
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 elements:", 19);
                pm_buffer_append_format(output_buffer, " (length: %lu)\n", (unsigned long) (cast->elements.size));

                size_t last_index = cast->elements.size;
                for (uint32_t index = 0; index < last_index; index++) {
                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);

                    if (index == last_index - 1) {
                        pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 ", 10);
                        pm_buffer_append_string(prefix_buffer, "    ", 4);
                    } else {
                        pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 ", 10);
                        pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    }

                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->elements.nodes[index], prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // opening_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 opening_loc:", 22);
                pm_location_t *location = &cast->opening_loc;
                if (location->start == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, ' ');
                    prettyprint_location(output_buffer, parser, location);
                    pm_buffer_append_string(output_buffer, " = \"", 4);
                    prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                    pm_buffer_append_string(output_buffer, "\"\n", 2);
                }
            }

            // closing_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 closing_loc:", 22);
                pm_location_t *location = &cast->closing_loc;
                if (location->start == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, ' ');
                    prettyprint_location(output_buffer, parser, location);
                    pm_buffer_append_string(output_buffer, " = \"", 4);
                    prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                    pm_buffer_append_string(output_buffer, "\"\n", 2);
                }
            }

            break;
        }
        case PM_ARRAY_PATTERN_NODE: {
            pm_array_pattern_node_t *cast = (pm_array_pattern_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ ArrayPatternNode (location: ", 30);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // constant
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 constant:", 19);
                if (cast->constant == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->constant, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // requireds
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 requireds:", 20);
                pm_buffer_append_format(output_buffer, " (length: %lu)\n", (unsigned long) (cast->requireds.size));

                size_t last_index = cast->requireds.size;
                for (uint32_t index = 0; index < last_index; index++) {
                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);

                    if (index == last_index - 1) {
                        pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 ", 10);
                        pm_buffer_append_string(prefix_buffer, "    ", 4);
                    } else {
                        pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 ", 10);
                        pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    }

                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->requireds.nodes[index], prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // rest
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 rest:", 15);
                if (cast->rest == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->rest, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // posts
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 posts:", 16);
                pm_buffer_append_format(output_buffer, " (length: %lu)\n", (unsigned long) (cast->posts.size));

                size_t last_index = cast->posts.size;
                for (uint32_t index = 0; index < last_index; index++) {
                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);

                    if (index == last_index - 1) {
                        pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 ", 10);
                        pm_buffer_append_string(prefix_buffer, "    ", 4);
                    } else {
                        pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 ", 10);
                        pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    }

                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->posts.nodes[index], prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // opening_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 opening_loc:", 22);
                pm_location_t *location = &cast->opening_loc;
                if (location->start == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, ' ');
                    prettyprint_location(output_buffer, parser, location);
                    pm_buffer_append_string(output_buffer, " = \"", 4);
                    prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                    pm_buffer_append_string(output_buffer, "\"\n", 2);
                }
            }

            // closing_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 closing_loc:", 22);
                pm_location_t *location = &cast->closing_loc;
                if (location->start == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, ' ');
                    prettyprint_location(output_buffer, parser, location);
                    pm_buffer_append_string(output_buffer, " = \"", 4);
                    prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                    pm_buffer_append_string(output_buffer, "\"\n", 2);
                }
            }

            break;
        }
        case PM_ASSOC_NODE: {
            pm_assoc_node_t *cast = (pm_assoc_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ AssocNode (location: ", 23);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // key
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 key:", 14);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->key, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            // value
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 value:", 16);
                if (cast->value == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // operator_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 operator_loc:", 23);
                pm_location_t *location = &cast->operator_loc;
                if (location->start == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, ' ');
                    prettyprint_location(output_buffer, parser, location);
                    pm_buffer_append_string(output_buffer, " = \"", 4);
                    prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                    pm_buffer_append_string(output_buffer, "\"\n", 2);
                }
            }

            break;
        }
        case PM_ASSOC_SPLAT_NODE: {
            pm_assoc_splat_node_t *cast = (pm_assoc_splat_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ AssocSplatNode (location: ", 28);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // value
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 value:", 16);
                if (cast->value == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // operator_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 operator_loc:", 23);
                pm_location_t *location = &cast->operator_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            break;
        }
        case PM_BACK_REFERENCE_READ_NODE: {
            pm_back_reference_read_node_t *cast = (pm_back_reference_read_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ BackReferenceReadNode (location: ", 35);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // name
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 name:", 15);
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_constant(output_buffer, parser, cast->name);
                pm_buffer_append_byte(output_buffer, '\n');
            }

            break;
        }
        case PM_BEGIN_NODE: {
            pm_begin_node_t *cast = (pm_begin_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ BeginNode (location: ", 23);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // begin_keyword_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 begin_keyword_loc:", 28);
                pm_location_t *location = &cast->begin_keyword_loc;
                if (location->start == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, ' ');
                    prettyprint_location(output_buffer, parser, location);
                    pm_buffer_append_string(output_buffer, " = \"", 4);
                    prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                    pm_buffer_append_string(output_buffer, "\"\n", 2);
                }
            }

            // statements
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 statements:", 21);
                if (cast->statements == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->statements, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // rescue_clause
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 rescue_clause:", 24);
                if (cast->rescue_clause == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->rescue_clause, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // else_clause
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 else_clause:", 22);
                if (cast->else_clause == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->else_clause, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // ensure_clause
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 ensure_clause:", 24);
                if (cast->ensure_clause == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->ensure_clause, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // end_keyword_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 end_keyword_loc:", 26);
                pm_location_t *location = &cast->end_keyword_loc;
                if (location->start == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, ' ');
                    prettyprint_location(output_buffer, parser, location);
                    pm_buffer_append_string(output_buffer, " = \"", 4);
                    prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                    pm_buffer_append_string(output_buffer, "\"\n", 2);
                }
            }

            break;
        }
        case PM_BLOCK_ARGUMENT_NODE: {
            pm_block_argument_node_t *cast = (pm_block_argument_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ BlockArgumentNode (location: ", 31);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // expression
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 expression:", 21);
                if (cast->expression == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->expression, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // operator_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 operator_loc:", 23);
                pm_location_t *location = &cast->operator_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            break;
        }
        case PM_BLOCK_LOCAL_VARIABLE_NODE: {
            pm_block_local_variable_node_t *cast = (pm_block_local_variable_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ BlockLocalVariableNode (location: ", 36);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // name
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 name:", 15);
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_constant(output_buffer, parser, cast->name);
                pm_buffer_append_byte(output_buffer, '\n');
            }

            break;
        }
        case PM_BLOCK_NODE: {
            pm_block_node_t *cast = (pm_block_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ BlockNode (location: ", 23);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // locals
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 locals:", 17);
                pm_buffer_append_string(output_buffer, " [", 2);
                for (uint32_t index = 0; index < cast->locals.size; index++) {
                    if (index != 0) pm_buffer_append_string(output_buffer, ", ", 2);
                    prettyprint_constant(output_buffer, parser, cast->locals.ids[index]);
                }
                pm_buffer_append_string(output_buffer, "]\n", 2);
            }

            // locals_body_index
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 locals_body_index:", 28);
                pm_buffer_append_format(output_buffer, " %d\n", cast->locals_body_index);
            }

            // parameters
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 parameters:", 21);
                if (cast->parameters == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->parameters, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // body
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 body:", 15);
                if (cast->body == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->body, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // opening_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 opening_loc:", 22);
                pm_location_t *location = &cast->opening_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // closing_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 closing_loc:", 22);
                pm_location_t *location = &cast->closing_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            break;
        }
        case PM_BLOCK_PARAMETER_NODE: {
            pm_block_parameter_node_t *cast = (pm_block_parameter_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ BlockParameterNode (location: ", 32);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // name
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 name:", 15);
                if (cast->name == 0) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, ' ');
                    prettyprint_constant(output_buffer, parser, cast->name);
                    pm_buffer_append_byte(output_buffer, '\n');
                }
            }

            // name_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 name_loc:", 19);
                pm_location_t *location = &cast->name_loc;
                if (location->start == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, ' ');
                    prettyprint_location(output_buffer, parser, location);
                    pm_buffer_append_string(output_buffer, " = \"", 4);
                    prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                    pm_buffer_append_string(output_buffer, "\"\n", 2);
                }
            }

            // operator_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 operator_loc:", 23);
                pm_location_t *location = &cast->operator_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            break;
        }
        case PM_BLOCK_PARAMETERS_NODE: {
            pm_block_parameters_node_t *cast = (pm_block_parameters_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ BlockParametersNode (location: ", 33);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // parameters
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 parameters:", 21);
                if (cast->parameters == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->parameters, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // locals
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 locals:", 17);
                pm_buffer_append_format(output_buffer, " (length: %lu)\n", (unsigned long) (cast->locals.size));

                size_t last_index = cast->locals.size;
                for (uint32_t index = 0; index < last_index; index++) {
                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);

                    if (index == last_index - 1) {
                        pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 ", 10);
                        pm_buffer_append_string(prefix_buffer, "    ", 4);
                    } else {
                        pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 ", 10);
                        pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    }

                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->locals.nodes[index], prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // opening_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 opening_loc:", 22);
                pm_location_t *location = &cast->opening_loc;
                if (location->start == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, ' ');
                    prettyprint_location(output_buffer, parser, location);
                    pm_buffer_append_string(output_buffer, " = \"", 4);
                    prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                    pm_buffer_append_string(output_buffer, "\"\n", 2);
                }
            }

            // closing_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 closing_loc:", 22);
                pm_location_t *location = &cast->closing_loc;
                if (location->start == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, ' ');
                    prettyprint_location(output_buffer, parser, location);
                    pm_buffer_append_string(output_buffer, " = \"", 4);
                    prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                    pm_buffer_append_string(output_buffer, "\"\n", 2);
                }
            }

            break;
        }
        case PM_BREAK_NODE: {
            pm_break_node_t *cast = (pm_break_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ BreakNode (location: ", 23);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // arguments
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 arguments:", 20);
                if (cast->arguments == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->arguments, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // keyword_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 keyword_loc:", 22);
                pm_location_t *location = &cast->keyword_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            break;
        }
        case PM_CALL_AND_WRITE_NODE: {
            pm_call_and_write_node_t *cast = (pm_call_and_write_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ CallAndWriteNode (location: ", 30);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // flags
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 flags:", 16);
                bool found = false;
                if (cast->base.flags & PM_CALL_NODE_FLAGS_SAFE_NAVIGATION) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " safe_navigation", 16);
                    found = true;
                }
                if (cast->base.flags & PM_CALL_NODE_FLAGS_VARIABLE_CALL) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " variable_call", 14);
                    found = true;
                }
                if (cast->base.flags & PM_CALL_NODE_FLAGS_ATTRIBUTE_WRITE) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " attribute_write", 16);
                    found = true;
                }
                if (!found) pm_buffer_append_string(output_buffer, " \xe2\x88\x85", 4);
                pm_buffer_append_byte(output_buffer, '\n');
            }

            // receiver
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 receiver:", 19);
                if (cast->receiver == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->receiver, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // call_operator_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 call_operator_loc:", 28);
                pm_location_t *location = &cast->call_operator_loc;
                if (location->start == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, ' ');
                    prettyprint_location(output_buffer, parser, location);
                    pm_buffer_append_string(output_buffer, " = \"", 4);
                    prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                    pm_buffer_append_string(output_buffer, "\"\n", 2);
                }
            }

            // message_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 message_loc:", 22);
                pm_location_t *location = &cast->message_loc;
                if (location->start == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, ' ');
                    prettyprint_location(output_buffer, parser, location);
                    pm_buffer_append_string(output_buffer, " = \"", 4);
                    prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                    pm_buffer_append_string(output_buffer, "\"\n", 2);
                }
            }

            // read_name
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 read_name:", 20);
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_constant(output_buffer, parser, cast->read_name);
                pm_buffer_append_byte(output_buffer, '\n');
            }

            // write_name
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 write_name:", 21);
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_constant(output_buffer, parser, cast->write_name);
                pm_buffer_append_byte(output_buffer, '\n');
            }

            // operator_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 operator_loc:", 23);
                pm_location_t *location = &cast->operator_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // value
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 value:", 16);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "    ", 4);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            break;
        }
        case PM_CALL_NODE: {
            pm_call_node_t *cast = (pm_call_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ CallNode (location: ", 22);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // flags
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 flags:", 16);
                bool found = false;
                if (cast->base.flags & PM_CALL_NODE_FLAGS_SAFE_NAVIGATION) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " safe_navigation", 16);
                    found = true;
                }
                if (cast->base.flags & PM_CALL_NODE_FLAGS_VARIABLE_CALL) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " variable_call", 14);
                    found = true;
                }
                if (cast->base.flags & PM_CALL_NODE_FLAGS_ATTRIBUTE_WRITE) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " attribute_write", 16);
                    found = true;
                }
                if (!found) pm_buffer_append_string(output_buffer, " \xe2\x88\x85", 4);
                pm_buffer_append_byte(output_buffer, '\n');
            }

            // receiver
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 receiver:", 19);
                if (cast->receiver == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->receiver, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // call_operator_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 call_operator_loc:", 28);
                pm_location_t *location = &cast->call_operator_loc;
                if (location->start == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, ' ');
                    prettyprint_location(output_buffer, parser, location);
                    pm_buffer_append_string(output_buffer, " = \"", 4);
                    prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                    pm_buffer_append_string(output_buffer, "\"\n", 2);
                }
            }

            // name
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 name:", 15);
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_constant(output_buffer, parser, cast->name);
                pm_buffer_append_byte(output_buffer, '\n');
            }

            // message_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 message_loc:", 22);
                pm_location_t *location = &cast->message_loc;
                if (location->start == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, ' ');
                    prettyprint_location(output_buffer, parser, location);
                    pm_buffer_append_string(output_buffer, " = \"", 4);
                    prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                    pm_buffer_append_string(output_buffer, "\"\n", 2);
                }
            }

            // opening_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 opening_loc:", 22);
                pm_location_t *location = &cast->opening_loc;
                if (location->start == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, ' ');
                    prettyprint_location(output_buffer, parser, location);
                    pm_buffer_append_string(output_buffer, " = \"", 4);
                    prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                    pm_buffer_append_string(output_buffer, "\"\n", 2);
                }
            }

            // arguments
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 arguments:", 20);
                if (cast->arguments == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->arguments, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // closing_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 closing_loc:", 22);
                pm_location_t *location = &cast->closing_loc;
                if (location->start == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, ' ');
                    prettyprint_location(output_buffer, parser, location);
                    pm_buffer_append_string(output_buffer, " = \"", 4);
                    prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                    pm_buffer_append_string(output_buffer, "\"\n", 2);
                }
            }

            // block
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 block:", 16);
                if (cast->block == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "    ", 4);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->block, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            break;
        }
        case PM_CALL_OPERATOR_WRITE_NODE: {
            pm_call_operator_write_node_t *cast = (pm_call_operator_write_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ CallOperatorWriteNode (location: ", 35);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // flags
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 flags:", 16);
                bool found = false;
                if (cast->base.flags & PM_CALL_NODE_FLAGS_SAFE_NAVIGATION) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " safe_navigation", 16);
                    found = true;
                }
                if (cast->base.flags & PM_CALL_NODE_FLAGS_VARIABLE_CALL) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " variable_call", 14);
                    found = true;
                }
                if (cast->base.flags & PM_CALL_NODE_FLAGS_ATTRIBUTE_WRITE) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " attribute_write", 16);
                    found = true;
                }
                if (!found) pm_buffer_append_string(output_buffer, " \xe2\x88\x85", 4);
                pm_buffer_append_byte(output_buffer, '\n');
            }

            // receiver
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 receiver:", 19);
                if (cast->receiver == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->receiver, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // call_operator_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 call_operator_loc:", 28);
                pm_location_t *location = &cast->call_operator_loc;
                if (location->start == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, ' ');
                    prettyprint_location(output_buffer, parser, location);
                    pm_buffer_append_string(output_buffer, " = \"", 4);
                    prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                    pm_buffer_append_string(output_buffer, "\"\n", 2);
                }
            }

            // message_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 message_loc:", 22);
                pm_location_t *location = &cast->message_loc;
                if (location->start == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, ' ');
                    prettyprint_location(output_buffer, parser, location);
                    pm_buffer_append_string(output_buffer, " = \"", 4);
                    prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                    pm_buffer_append_string(output_buffer, "\"\n", 2);
                }
            }

            // read_name
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 read_name:", 20);
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_constant(output_buffer, parser, cast->read_name);
                pm_buffer_append_byte(output_buffer, '\n');
            }

            // write_name
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 write_name:", 21);
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_constant(output_buffer, parser, cast->write_name);
                pm_buffer_append_byte(output_buffer, '\n');
            }

            // operator
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 operator:", 19);
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_constant(output_buffer, parser, cast->operator);
                pm_buffer_append_byte(output_buffer, '\n');
            }

            // operator_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 operator_loc:", 23);
                pm_location_t *location = &cast->operator_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // value
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 value:", 16);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "    ", 4);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            break;
        }
        case PM_CALL_OR_WRITE_NODE: {
            pm_call_or_write_node_t *cast = (pm_call_or_write_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ CallOrWriteNode (location: ", 29);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // flags
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 flags:", 16);
                bool found = false;
                if (cast->base.flags & PM_CALL_NODE_FLAGS_SAFE_NAVIGATION) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " safe_navigation", 16);
                    found = true;
                }
                if (cast->base.flags & PM_CALL_NODE_FLAGS_VARIABLE_CALL) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " variable_call", 14);
                    found = true;
                }
                if (cast->base.flags & PM_CALL_NODE_FLAGS_ATTRIBUTE_WRITE) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " attribute_write", 16);
                    found = true;
                }
                if (!found) pm_buffer_append_string(output_buffer, " \xe2\x88\x85", 4);
                pm_buffer_append_byte(output_buffer, '\n');
            }

            // receiver
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 receiver:", 19);
                if (cast->receiver == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->receiver, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // call_operator_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 call_operator_loc:", 28);
                pm_location_t *location = &cast->call_operator_loc;
                if (location->start == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, ' ');
                    prettyprint_location(output_buffer, parser, location);
                    pm_buffer_append_string(output_buffer, " = \"", 4);
                    prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                    pm_buffer_append_string(output_buffer, "\"\n", 2);
                }
            }

            // message_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 message_loc:", 22);
                pm_location_t *location = &cast->message_loc;
                if (location->start == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, ' ');
                    prettyprint_location(output_buffer, parser, location);
                    pm_buffer_append_string(output_buffer, " = \"", 4);
                    prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                    pm_buffer_append_string(output_buffer, "\"\n", 2);
                }
            }

            // read_name
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 read_name:", 20);
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_constant(output_buffer, parser, cast->read_name);
                pm_buffer_append_byte(output_buffer, '\n');
            }

            // write_name
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 write_name:", 21);
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_constant(output_buffer, parser, cast->write_name);
                pm_buffer_append_byte(output_buffer, '\n');
            }

            // operator_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 operator_loc:", 23);
                pm_location_t *location = &cast->operator_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // value
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 value:", 16);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "    ", 4);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            break;
        }
        case PM_CALL_TARGET_NODE: {
            pm_call_target_node_t *cast = (pm_call_target_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ CallTargetNode (location: ", 28);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // flags
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 flags:", 16);
                bool found = false;
                if (cast->base.flags & PM_CALL_NODE_FLAGS_SAFE_NAVIGATION) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " safe_navigation", 16);
                    found = true;
                }
                if (cast->base.flags & PM_CALL_NODE_FLAGS_VARIABLE_CALL) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " variable_call", 14);
                    found = true;
                }
                if (cast->base.flags & PM_CALL_NODE_FLAGS_ATTRIBUTE_WRITE) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " attribute_write", 16);
                    found = true;
                }
                if (!found) pm_buffer_append_string(output_buffer, " \xe2\x88\x85", 4);
                pm_buffer_append_byte(output_buffer, '\n');
            }

            // receiver
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 receiver:", 19);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->receiver, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            // call_operator_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 call_operator_loc:", 28);
                pm_location_t *location = &cast->call_operator_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // name
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 name:", 15);
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_constant(output_buffer, parser, cast->name);
                pm_buffer_append_byte(output_buffer, '\n');
            }

            // message_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 message_loc:", 22);
                pm_location_t *location = &cast->message_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            break;
        }
        case PM_CAPTURE_PATTERN_NODE: {
            pm_capture_pattern_node_t *cast = (pm_capture_pattern_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ CapturePatternNode (location: ", 32);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // value
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 value:", 16);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            // target
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 target:", 17);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->target, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            // operator_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 operator_loc:", 23);
                pm_location_t *location = &cast->operator_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            break;
        }
        case PM_CASE_MATCH_NODE: {
            pm_case_match_node_t *cast = (pm_case_match_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ CaseMatchNode (location: ", 27);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // predicate
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 predicate:", 20);
                if (cast->predicate == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->predicate, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // conditions
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 conditions:", 21);
                pm_buffer_append_format(output_buffer, " (length: %lu)\n", (unsigned long) (cast->conditions.size));

                size_t last_index = cast->conditions.size;
                for (uint32_t index = 0; index < last_index; index++) {
                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);

                    if (index == last_index - 1) {
                        pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 ", 10);
                        pm_buffer_append_string(prefix_buffer, "    ", 4);
                    } else {
                        pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 ", 10);
                        pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    }

                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->conditions.nodes[index], prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // consequent
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 consequent:", 21);
                if (cast->consequent == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->consequent, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // case_keyword_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 case_keyword_loc:", 27);
                pm_location_t *location = &cast->case_keyword_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // end_keyword_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 end_keyword_loc:", 26);
                pm_location_t *location = &cast->end_keyword_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            break;
        }
        case PM_CASE_NODE: {
            pm_case_node_t *cast = (pm_case_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ CaseNode (location: ", 22);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // predicate
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 predicate:", 20);
                if (cast->predicate == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->predicate, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // conditions
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 conditions:", 21);
                pm_buffer_append_format(output_buffer, " (length: %lu)\n", (unsigned long) (cast->conditions.size));

                size_t last_index = cast->conditions.size;
                for (uint32_t index = 0; index < last_index; index++) {
                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);

                    if (index == last_index - 1) {
                        pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 ", 10);
                        pm_buffer_append_string(prefix_buffer, "    ", 4);
                    } else {
                        pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 ", 10);
                        pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    }

                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->conditions.nodes[index], prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // consequent
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 consequent:", 21);
                if (cast->consequent == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->consequent, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // case_keyword_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 case_keyword_loc:", 27);
                pm_location_t *location = &cast->case_keyword_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // end_keyword_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 end_keyword_loc:", 26);
                pm_location_t *location = &cast->end_keyword_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            break;
        }
        case PM_CLASS_NODE: {
            pm_class_node_t *cast = (pm_class_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ ClassNode (location: ", 23);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // locals
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 locals:", 17);
                pm_buffer_append_string(output_buffer, " [", 2);
                for (uint32_t index = 0; index < cast->locals.size; index++) {
                    if (index != 0) pm_buffer_append_string(output_buffer, ", ", 2);
                    prettyprint_constant(output_buffer, parser, cast->locals.ids[index]);
                }
                pm_buffer_append_string(output_buffer, "]\n", 2);
            }

            // class_keyword_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 class_keyword_loc:", 28);
                pm_location_t *location = &cast->class_keyword_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // constant_path
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 constant_path:", 24);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->constant_path, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            // inheritance_operator_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 inheritance_operator_loc:", 35);
                pm_location_t *location = &cast->inheritance_operator_loc;
                if (location->start == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, ' ');
                    prettyprint_location(output_buffer, parser, location);
                    pm_buffer_append_string(output_buffer, " = \"", 4);
                    prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                    pm_buffer_append_string(output_buffer, "\"\n", 2);
                }
            }

            // superclass
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 superclass:", 21);
                if (cast->superclass == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->superclass, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // body
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 body:", 15);
                if (cast->body == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->body, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // end_keyword_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 end_keyword_loc:", 26);
                pm_location_t *location = &cast->end_keyword_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // name
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 name:", 15);
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_constant(output_buffer, parser, cast->name);
                pm_buffer_append_byte(output_buffer, '\n');
            }

            break;
        }
        case PM_CLASS_VARIABLE_AND_WRITE_NODE: {
            pm_class_variable_and_write_node_t *cast = (pm_class_variable_and_write_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ ClassVariableAndWriteNode (location: ", 39);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // name
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 name:", 15);
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_constant(output_buffer, parser, cast->name);
                pm_buffer_append_byte(output_buffer, '\n');
            }

            // name_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 name_loc:", 19);
                pm_location_t *location = &cast->name_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // operator_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 operator_loc:", 23);
                pm_location_t *location = &cast->operator_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // value
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 value:", 16);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "    ", 4);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            break;
        }
        case PM_CLASS_VARIABLE_OPERATOR_WRITE_NODE: {
            pm_class_variable_operator_write_node_t *cast = (pm_class_variable_operator_write_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ ClassVariableOperatorWriteNode (location: ", 44);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // name
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 name:", 15);
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_constant(output_buffer, parser, cast->name);
                pm_buffer_append_byte(output_buffer, '\n');
            }

            // name_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 name_loc:", 19);
                pm_location_t *location = &cast->name_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // operator_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 operator_loc:", 23);
                pm_location_t *location = &cast->operator_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // value
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 value:", 16);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            // operator
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 operator:", 19);
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_constant(output_buffer, parser, cast->operator);
                pm_buffer_append_byte(output_buffer, '\n');
            }

            break;
        }
        case PM_CLASS_VARIABLE_OR_WRITE_NODE: {
            pm_class_variable_or_write_node_t *cast = (pm_class_variable_or_write_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ ClassVariableOrWriteNode (location: ", 38);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // name
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 name:", 15);
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_constant(output_buffer, parser, cast->name);
                pm_buffer_append_byte(output_buffer, '\n');
            }

            // name_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 name_loc:", 19);
                pm_location_t *location = &cast->name_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // operator_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 operator_loc:", 23);
                pm_location_t *location = &cast->operator_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // value
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 value:", 16);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "    ", 4);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            break;
        }
        case PM_CLASS_VARIABLE_READ_NODE: {
            pm_class_variable_read_node_t *cast = (pm_class_variable_read_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ ClassVariableReadNode (location: ", 35);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // name
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 name:", 15);
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_constant(output_buffer, parser, cast->name);
                pm_buffer_append_byte(output_buffer, '\n');
            }

            break;
        }
        case PM_CLASS_VARIABLE_TARGET_NODE: {
            pm_class_variable_target_node_t *cast = (pm_class_variable_target_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ ClassVariableTargetNode (location: ", 37);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // name
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 name:", 15);
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_constant(output_buffer, parser, cast->name);
                pm_buffer_append_byte(output_buffer, '\n');
            }

            break;
        }
        case PM_CLASS_VARIABLE_WRITE_NODE: {
            pm_class_variable_write_node_t *cast = (pm_class_variable_write_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ ClassVariableWriteNode (location: ", 36);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // name
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 name:", 15);
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_constant(output_buffer, parser, cast->name);
                pm_buffer_append_byte(output_buffer, '\n');
            }

            // name_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 name_loc:", 19);
                pm_location_t *location = &cast->name_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // value
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 value:", 16);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            // operator_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 operator_loc:", 23);
                pm_location_t *location = &cast->operator_loc;
                if (location->start == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, ' ');
                    prettyprint_location(output_buffer, parser, location);
                    pm_buffer_append_string(output_buffer, " = \"", 4);
                    prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                    pm_buffer_append_string(output_buffer, "\"\n", 2);
                }
            }

            break;
        }
        case PM_CONSTANT_AND_WRITE_NODE: {
            pm_constant_and_write_node_t *cast = (pm_constant_and_write_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ ConstantAndWriteNode (location: ", 34);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // name
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 name:", 15);
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_constant(output_buffer, parser, cast->name);
                pm_buffer_append_byte(output_buffer, '\n');
            }

            // name_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 name_loc:", 19);
                pm_location_t *location = &cast->name_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // operator_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 operator_loc:", 23);
                pm_location_t *location = &cast->operator_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // value
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 value:", 16);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "    ", 4);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            break;
        }
        case PM_CONSTANT_OPERATOR_WRITE_NODE: {
            pm_constant_operator_write_node_t *cast = (pm_constant_operator_write_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ ConstantOperatorWriteNode (location: ", 39);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // name
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 name:", 15);
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_constant(output_buffer, parser, cast->name);
                pm_buffer_append_byte(output_buffer, '\n');
            }

            // name_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 name_loc:", 19);
                pm_location_t *location = &cast->name_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // operator_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 operator_loc:", 23);
                pm_location_t *location = &cast->operator_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // value
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 value:", 16);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            // operator
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 operator:", 19);
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_constant(output_buffer, parser, cast->operator);
                pm_buffer_append_byte(output_buffer, '\n');
            }

            break;
        }
        case PM_CONSTANT_OR_WRITE_NODE: {
            pm_constant_or_write_node_t *cast = (pm_constant_or_write_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ ConstantOrWriteNode (location: ", 33);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // name
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 name:", 15);
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_constant(output_buffer, parser, cast->name);
                pm_buffer_append_byte(output_buffer, '\n');
            }

            // name_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 name_loc:", 19);
                pm_location_t *location = &cast->name_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // operator_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 operator_loc:", 23);
                pm_location_t *location = &cast->operator_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // value
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 value:", 16);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "    ", 4);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            break;
        }
        case PM_CONSTANT_PATH_AND_WRITE_NODE: {
            pm_constant_path_and_write_node_t *cast = (pm_constant_path_and_write_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ ConstantPathAndWriteNode (location: ", 38);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // target
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 target:", 17);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->target, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            // operator_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 operator_loc:", 23);
                pm_location_t *location = &cast->operator_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // value
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 value:", 16);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "    ", 4);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            break;
        }
        case PM_CONSTANT_PATH_NODE: {
            pm_constant_path_node_t *cast = (pm_constant_path_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ ConstantPathNode (location: ", 30);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // parent
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 parent:", 17);
                if (cast->parent == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->parent, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // child
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 child:", 16);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->child, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            // delimiter_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 delimiter_loc:", 24);
                pm_location_t *location = &cast->delimiter_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            break;
        }
        case PM_CONSTANT_PATH_OPERATOR_WRITE_NODE: {
            pm_constant_path_operator_write_node_t *cast = (pm_constant_path_operator_write_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ ConstantPathOperatorWriteNode (location: ", 43);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // target
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 target:", 17);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->target, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            // operator_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 operator_loc:", 23);
                pm_location_t *location = &cast->operator_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // value
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 value:", 16);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            // operator
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 operator:", 19);
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_constant(output_buffer, parser, cast->operator);
                pm_buffer_append_byte(output_buffer, '\n');
            }

            break;
        }
        case PM_CONSTANT_PATH_OR_WRITE_NODE: {
            pm_constant_path_or_write_node_t *cast = (pm_constant_path_or_write_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ ConstantPathOrWriteNode (location: ", 37);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // target
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 target:", 17);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->target, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            // operator_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 operator_loc:", 23);
                pm_location_t *location = &cast->operator_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // value
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 value:", 16);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "    ", 4);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            break;
        }
        case PM_CONSTANT_PATH_TARGET_NODE: {
            pm_constant_path_target_node_t *cast = (pm_constant_path_target_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ ConstantPathTargetNode (location: ", 36);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // parent
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 parent:", 17);
                if (cast->parent == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->parent, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // child
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 child:", 16);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->child, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            // delimiter_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 delimiter_loc:", 24);
                pm_location_t *location = &cast->delimiter_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            break;
        }
        case PM_CONSTANT_PATH_WRITE_NODE: {
            pm_constant_path_write_node_t *cast = (pm_constant_path_write_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ ConstantPathWriteNode (location: ", 35);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // target
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 target:", 17);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->target, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            // operator_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 operator_loc:", 23);
                pm_location_t *location = &cast->operator_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // value
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 value:", 16);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "    ", 4);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            break;
        }
        case PM_CONSTANT_READ_NODE: {
            pm_constant_read_node_t *cast = (pm_constant_read_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ ConstantReadNode (location: ", 30);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // name
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 name:", 15);
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_constant(output_buffer, parser, cast->name);
                pm_buffer_append_byte(output_buffer, '\n');
            }

            break;
        }
        case PM_CONSTANT_TARGET_NODE: {
            pm_constant_target_node_t *cast = (pm_constant_target_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ ConstantTargetNode (location: ", 32);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // name
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 name:", 15);
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_constant(output_buffer, parser, cast->name);
                pm_buffer_append_byte(output_buffer, '\n');
            }

            break;
        }
        case PM_CONSTANT_WRITE_NODE: {
            pm_constant_write_node_t *cast = (pm_constant_write_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ ConstantWriteNode (location: ", 31);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // name
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 name:", 15);
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_constant(output_buffer, parser, cast->name);
                pm_buffer_append_byte(output_buffer, '\n');
            }

            // name_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 name_loc:", 19);
                pm_location_t *location = &cast->name_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // value
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 value:", 16);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            // operator_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 operator_loc:", 23);
                pm_location_t *location = &cast->operator_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            break;
        }
        case PM_DEF_NODE: {
            pm_def_node_t *cast = (pm_def_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ DefNode (location: ", 21);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // name
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 name:", 15);
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_constant(output_buffer, parser, cast->name);
                pm_buffer_append_byte(output_buffer, '\n');
            }

            // name_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 name_loc:", 19);
                pm_location_t *location = &cast->name_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // receiver
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 receiver:", 19);
                if (cast->receiver == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->receiver, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // parameters
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 parameters:", 21);
                if (cast->parameters == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->parameters, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // body
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 body:", 15);
                if (cast->body == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->body, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // locals
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 locals:", 17);
                pm_buffer_append_string(output_buffer, " [", 2);
                for (uint32_t index = 0; index < cast->locals.size; index++) {
                    if (index != 0) pm_buffer_append_string(output_buffer, ", ", 2);
                    prettyprint_constant(output_buffer, parser, cast->locals.ids[index]);
                }
                pm_buffer_append_string(output_buffer, "]\n", 2);
            }

            // locals_body_index
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 locals_body_index:", 28);
                pm_buffer_append_format(output_buffer, " %d\n", cast->locals_body_index);
            }

            // def_keyword_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 def_keyword_loc:", 26);
                pm_location_t *location = &cast->def_keyword_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // operator_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 operator_loc:", 23);
                pm_location_t *location = &cast->operator_loc;
                if (location->start == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, ' ');
                    prettyprint_location(output_buffer, parser, location);
                    pm_buffer_append_string(output_buffer, " = \"", 4);
                    prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                    pm_buffer_append_string(output_buffer, "\"\n", 2);
                }
            }

            // lparen_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 lparen_loc:", 21);
                pm_location_t *location = &cast->lparen_loc;
                if (location->start == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, ' ');
                    prettyprint_location(output_buffer, parser, location);
                    pm_buffer_append_string(output_buffer, " = \"", 4);
                    prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                    pm_buffer_append_string(output_buffer, "\"\n", 2);
                }
            }

            // rparen_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 rparen_loc:", 21);
                pm_location_t *location = &cast->rparen_loc;
                if (location->start == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, ' ');
                    prettyprint_location(output_buffer, parser, location);
                    pm_buffer_append_string(output_buffer, " = \"", 4);
                    prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                    pm_buffer_append_string(output_buffer, "\"\n", 2);
                }
            }

            // equal_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 equal_loc:", 20);
                pm_location_t *location = &cast->equal_loc;
                if (location->start == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, ' ');
                    prettyprint_location(output_buffer, parser, location);
                    pm_buffer_append_string(output_buffer, " = \"", 4);
                    prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                    pm_buffer_append_string(output_buffer, "\"\n", 2);
                }
            }

            // end_keyword_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 end_keyword_loc:", 26);
                pm_location_t *location = &cast->end_keyword_loc;
                if (location->start == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, ' ');
                    prettyprint_location(output_buffer, parser, location);
                    pm_buffer_append_string(output_buffer, " = \"", 4);
                    prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                    pm_buffer_append_string(output_buffer, "\"\n", 2);
                }
            }

            break;
        }
        case PM_DEFINED_NODE: {
            pm_defined_node_t *cast = (pm_defined_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ DefinedNode (location: ", 25);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // lparen_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 lparen_loc:", 21);
                pm_location_t *location = &cast->lparen_loc;
                if (location->start == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, ' ');
                    prettyprint_location(output_buffer, parser, location);
                    pm_buffer_append_string(output_buffer, " = \"", 4);
                    prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                    pm_buffer_append_string(output_buffer, "\"\n", 2);
                }
            }

            // value
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 value:", 16);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            // rparen_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 rparen_loc:", 21);
                pm_location_t *location = &cast->rparen_loc;
                if (location->start == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, ' ');
                    prettyprint_location(output_buffer, parser, location);
                    pm_buffer_append_string(output_buffer, " = \"", 4);
                    prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                    pm_buffer_append_string(output_buffer, "\"\n", 2);
                }
            }

            // keyword_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 keyword_loc:", 22);
                pm_location_t *location = &cast->keyword_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            break;
        }
        case PM_ELSE_NODE: {
            pm_else_node_t *cast = (pm_else_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ ElseNode (location: ", 22);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // else_keyword_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 else_keyword_loc:", 27);
                pm_location_t *location = &cast->else_keyword_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // statements
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 statements:", 21);
                if (cast->statements == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->statements, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // end_keyword_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 end_keyword_loc:", 26);
                pm_location_t *location = &cast->end_keyword_loc;
                if (location->start == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, ' ');
                    prettyprint_location(output_buffer, parser, location);
                    pm_buffer_append_string(output_buffer, " = \"", 4);
                    prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                    pm_buffer_append_string(output_buffer, "\"\n", 2);
                }
            }

            break;
        }
        case PM_EMBEDDED_STATEMENTS_NODE: {
            pm_embedded_statements_node_t *cast = (pm_embedded_statements_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ EmbeddedStatementsNode (location: ", 36);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // opening_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 opening_loc:", 22);
                pm_location_t *location = &cast->opening_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // statements
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 statements:", 21);
                if (cast->statements == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->statements, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // closing_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 closing_loc:", 22);
                pm_location_t *location = &cast->closing_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            break;
        }
        case PM_EMBEDDED_VARIABLE_NODE: {
            pm_embedded_variable_node_t *cast = (pm_embedded_variable_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ EmbeddedVariableNode (location: ", 34);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // operator_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 operator_loc:", 23);
                pm_location_t *location = &cast->operator_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // variable
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 variable:", 19);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "    ", 4);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->variable, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            break;
        }
        case PM_ENSURE_NODE: {
            pm_ensure_node_t *cast = (pm_ensure_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ EnsureNode (location: ", 24);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // ensure_keyword_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 ensure_keyword_loc:", 29);
                pm_location_t *location = &cast->ensure_keyword_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // statements
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 statements:", 21);
                if (cast->statements == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->statements, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // end_keyword_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 end_keyword_loc:", 26);
                pm_location_t *location = &cast->end_keyword_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            break;
        }
        case PM_FALSE_NODE: {
            pm_buffer_append_string(output_buffer, "@ FalseNode (location: ", 23);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            break;
        }
        case PM_FIND_PATTERN_NODE: {
            pm_find_pattern_node_t *cast = (pm_find_pattern_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ FindPatternNode (location: ", 29);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // constant
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 constant:", 19);
                if (cast->constant == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->constant, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // left
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 left:", 15);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->left, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            // requireds
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 requireds:", 20);
                pm_buffer_append_format(output_buffer, " (length: %lu)\n", (unsigned long) (cast->requireds.size));

                size_t last_index = cast->requireds.size;
                for (uint32_t index = 0; index < last_index; index++) {
                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);

                    if (index == last_index - 1) {
                        pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 ", 10);
                        pm_buffer_append_string(prefix_buffer, "    ", 4);
                    } else {
                        pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 ", 10);
                        pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    }

                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->requireds.nodes[index], prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // right
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 right:", 16);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->right, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            // opening_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 opening_loc:", 22);
                pm_location_t *location = &cast->opening_loc;
                if (location->start == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, ' ');
                    prettyprint_location(output_buffer, parser, location);
                    pm_buffer_append_string(output_buffer, " = \"", 4);
                    prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                    pm_buffer_append_string(output_buffer, "\"\n", 2);
                }
            }

            // closing_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 closing_loc:", 22);
                pm_location_t *location = &cast->closing_loc;
                if (location->start == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, ' ');
                    prettyprint_location(output_buffer, parser, location);
                    pm_buffer_append_string(output_buffer, " = \"", 4);
                    prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                    pm_buffer_append_string(output_buffer, "\"\n", 2);
                }
            }

            break;
        }
        case PM_FLIP_FLOP_NODE: {
            pm_flip_flop_node_t *cast = (pm_flip_flop_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ FlipFlopNode (location: ", 26);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // flags
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 flags:", 16);
                bool found = false;
                if (cast->base.flags & PM_RANGE_FLAGS_EXCLUDE_END) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " exclude_end", 12);
                    found = true;
                }
                if (!found) pm_buffer_append_string(output_buffer, " \xe2\x88\x85", 4);
                pm_buffer_append_byte(output_buffer, '\n');
            }

            // left
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 left:", 15);
                if (cast->left == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->left, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // right
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 right:", 16);
                if (cast->right == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->right, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // operator_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 operator_loc:", 23);
                pm_location_t *location = &cast->operator_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            break;
        }
        case PM_FLOAT_NODE: {
            pm_buffer_append_string(output_buffer, "@ FloatNode (location: ", 23);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            break;
        }
        case PM_FOR_NODE: {
            pm_for_node_t *cast = (pm_for_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ ForNode (location: ", 21);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // index
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 index:", 16);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->index, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            // collection
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 collection:", 21);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->collection, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            // statements
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 statements:", 21);
                if (cast->statements == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->statements, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // for_keyword_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 for_keyword_loc:", 26);
                pm_location_t *location = &cast->for_keyword_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // in_keyword_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 in_keyword_loc:", 25);
                pm_location_t *location = &cast->in_keyword_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // do_keyword_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 do_keyword_loc:", 25);
                pm_location_t *location = &cast->do_keyword_loc;
                if (location->start == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, ' ');
                    prettyprint_location(output_buffer, parser, location);
                    pm_buffer_append_string(output_buffer, " = \"", 4);
                    prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                    pm_buffer_append_string(output_buffer, "\"\n", 2);
                }
            }

            // end_keyword_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 end_keyword_loc:", 26);
                pm_location_t *location = &cast->end_keyword_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            break;
        }
        case PM_FORWARDING_ARGUMENTS_NODE: {
            pm_buffer_append_string(output_buffer, "@ ForwardingArgumentsNode (location: ", 37);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            break;
        }
        case PM_FORWARDING_PARAMETER_NODE: {
            pm_buffer_append_string(output_buffer, "@ ForwardingParameterNode (location: ", 37);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            break;
        }
        case PM_FORWARDING_SUPER_NODE: {
            pm_forwarding_super_node_t *cast = (pm_forwarding_super_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ ForwardingSuperNode (location: ", 33);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // block
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 block:", 16);
                if (cast->block == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "    ", 4);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->block, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            break;
        }
        case PM_GLOBAL_VARIABLE_AND_WRITE_NODE: {
            pm_global_variable_and_write_node_t *cast = (pm_global_variable_and_write_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ GlobalVariableAndWriteNode (location: ", 40);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // name
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 name:", 15);
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_constant(output_buffer, parser, cast->name);
                pm_buffer_append_byte(output_buffer, '\n');
            }

            // name_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 name_loc:", 19);
                pm_location_t *location = &cast->name_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // operator_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 operator_loc:", 23);
                pm_location_t *location = &cast->operator_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // value
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 value:", 16);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "    ", 4);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            break;
        }
        case PM_GLOBAL_VARIABLE_OPERATOR_WRITE_NODE: {
            pm_global_variable_operator_write_node_t *cast = (pm_global_variable_operator_write_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ GlobalVariableOperatorWriteNode (location: ", 45);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // name
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 name:", 15);
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_constant(output_buffer, parser, cast->name);
                pm_buffer_append_byte(output_buffer, '\n');
            }

            // name_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 name_loc:", 19);
                pm_location_t *location = &cast->name_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // operator_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 operator_loc:", 23);
                pm_location_t *location = &cast->operator_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // value
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 value:", 16);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            // operator
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 operator:", 19);
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_constant(output_buffer, parser, cast->operator);
                pm_buffer_append_byte(output_buffer, '\n');
            }

            break;
        }
        case PM_GLOBAL_VARIABLE_OR_WRITE_NODE: {
            pm_global_variable_or_write_node_t *cast = (pm_global_variable_or_write_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ GlobalVariableOrWriteNode (location: ", 39);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // name
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 name:", 15);
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_constant(output_buffer, parser, cast->name);
                pm_buffer_append_byte(output_buffer, '\n');
            }

            // name_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 name_loc:", 19);
                pm_location_t *location = &cast->name_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // operator_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 operator_loc:", 23);
                pm_location_t *location = &cast->operator_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // value
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 value:", 16);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "    ", 4);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            break;
        }
        case PM_GLOBAL_VARIABLE_READ_NODE: {
            pm_global_variable_read_node_t *cast = (pm_global_variable_read_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ GlobalVariableReadNode (location: ", 36);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // name
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 name:", 15);
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_constant(output_buffer, parser, cast->name);
                pm_buffer_append_byte(output_buffer, '\n');
            }

            break;
        }
        case PM_GLOBAL_VARIABLE_TARGET_NODE: {
            pm_global_variable_target_node_t *cast = (pm_global_variable_target_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ GlobalVariableTargetNode (location: ", 38);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // name
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 name:", 15);
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_constant(output_buffer, parser, cast->name);
                pm_buffer_append_byte(output_buffer, '\n');
            }

            break;
        }
        case PM_GLOBAL_VARIABLE_WRITE_NODE: {
            pm_global_variable_write_node_t *cast = (pm_global_variable_write_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ GlobalVariableWriteNode (location: ", 37);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // name
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 name:", 15);
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_constant(output_buffer, parser, cast->name);
                pm_buffer_append_byte(output_buffer, '\n');
            }

            // name_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 name_loc:", 19);
                pm_location_t *location = &cast->name_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // value
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 value:", 16);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            // operator_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 operator_loc:", 23);
                pm_location_t *location = &cast->operator_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            break;
        }
        case PM_HASH_NODE: {
            pm_hash_node_t *cast = (pm_hash_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ HashNode (location: ", 22);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // opening_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 opening_loc:", 22);
                pm_location_t *location = &cast->opening_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // elements
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 elements:", 19);
                pm_buffer_append_format(output_buffer, " (length: %lu)\n", (unsigned long) (cast->elements.size));

                size_t last_index = cast->elements.size;
                for (uint32_t index = 0; index < last_index; index++) {
                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);

                    if (index == last_index - 1) {
                        pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 ", 10);
                        pm_buffer_append_string(prefix_buffer, "    ", 4);
                    } else {
                        pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 ", 10);
                        pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    }

                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->elements.nodes[index], prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // closing_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 closing_loc:", 22);
                pm_location_t *location = &cast->closing_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            break;
        }
        case PM_HASH_PATTERN_NODE: {
            pm_hash_pattern_node_t *cast = (pm_hash_pattern_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ HashPatternNode (location: ", 29);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // constant
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 constant:", 19);
                if (cast->constant == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->constant, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // elements
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 elements:", 19);
                pm_buffer_append_format(output_buffer, " (length: %lu)\n", (unsigned long) (cast->elements.size));

                size_t last_index = cast->elements.size;
                for (uint32_t index = 0; index < last_index; index++) {
                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);

                    if (index == last_index - 1) {
                        pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 ", 10);
                        pm_buffer_append_string(prefix_buffer, "    ", 4);
                    } else {
                        pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 ", 10);
                        pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    }

                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->elements.nodes[index], prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // rest
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 rest:", 15);
                if (cast->rest == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->rest, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // opening_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 opening_loc:", 22);
                pm_location_t *location = &cast->opening_loc;
                if (location->start == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, ' ');
                    prettyprint_location(output_buffer, parser, location);
                    pm_buffer_append_string(output_buffer, " = \"", 4);
                    prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                    pm_buffer_append_string(output_buffer, "\"\n", 2);
                }
            }

            // closing_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 closing_loc:", 22);
                pm_location_t *location = &cast->closing_loc;
                if (location->start == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, ' ');
                    prettyprint_location(output_buffer, parser, location);
                    pm_buffer_append_string(output_buffer, " = \"", 4);
                    prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                    pm_buffer_append_string(output_buffer, "\"\n", 2);
                }
            }

            break;
        }
        case PM_IF_NODE: {
            pm_if_node_t *cast = (pm_if_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ IfNode (location: ", 20);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // if_keyword_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 if_keyword_loc:", 25);
                pm_location_t *location = &cast->if_keyword_loc;
                if (location->start == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, ' ');
                    prettyprint_location(output_buffer, parser, location);
                    pm_buffer_append_string(output_buffer, " = \"", 4);
                    prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                    pm_buffer_append_string(output_buffer, "\"\n", 2);
                }
            }

            // predicate
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 predicate:", 20);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->predicate, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            // then_keyword_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 then_keyword_loc:", 27);
                pm_location_t *location = &cast->then_keyword_loc;
                if (location->start == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, ' ');
                    prettyprint_location(output_buffer, parser, location);
                    pm_buffer_append_string(output_buffer, " = \"", 4);
                    prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                    pm_buffer_append_string(output_buffer, "\"\n", 2);
                }
            }

            // statements
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 statements:", 21);
                if (cast->statements == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->statements, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // consequent
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 consequent:", 21);
                if (cast->consequent == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->consequent, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // end_keyword_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 end_keyword_loc:", 26);
                pm_location_t *location = &cast->end_keyword_loc;
                if (location->start == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, ' ');
                    prettyprint_location(output_buffer, parser, location);
                    pm_buffer_append_string(output_buffer, " = \"", 4);
                    prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                    pm_buffer_append_string(output_buffer, "\"\n", 2);
                }
            }

            break;
        }
        case PM_IMAGINARY_NODE: {
            pm_imaginary_node_t *cast = (pm_imaginary_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ ImaginaryNode (location: ", 27);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // numeric
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 numeric:", 18);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "    ", 4);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->numeric, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            break;
        }
        case PM_IMPLICIT_NODE: {
            pm_implicit_node_t *cast = (pm_implicit_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ ImplicitNode (location: ", 26);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // value
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 value:", 16);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "    ", 4);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            break;
        }
        case PM_IMPLICIT_REST_NODE: {
            pm_buffer_append_string(output_buffer, "@ ImplicitRestNode (location: ", 30);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            break;
        }
        case PM_IN_NODE: {
            pm_in_node_t *cast = (pm_in_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ InNode (location: ", 20);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // pattern
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 pattern:", 18);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->pattern, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            // statements
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 statements:", 21);
                if (cast->statements == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->statements, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // in_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 in_loc:", 17);
                pm_location_t *location = &cast->in_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // then_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 then_loc:", 19);
                pm_location_t *location = &cast->then_loc;
                if (location->start == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, ' ');
                    prettyprint_location(output_buffer, parser, location);
                    pm_buffer_append_string(output_buffer, " = \"", 4);
                    prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                    pm_buffer_append_string(output_buffer, "\"\n", 2);
                }
            }

            break;
        }
        case PM_INDEX_AND_WRITE_NODE: {
            pm_index_and_write_node_t *cast = (pm_index_and_write_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ IndexAndWriteNode (location: ", 31);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // flags
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 flags:", 16);
                bool found = false;
                if (cast->base.flags & PM_CALL_NODE_FLAGS_SAFE_NAVIGATION) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " safe_navigation", 16);
                    found = true;
                }
                if (cast->base.flags & PM_CALL_NODE_FLAGS_VARIABLE_CALL) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " variable_call", 14);
                    found = true;
                }
                if (cast->base.flags & PM_CALL_NODE_FLAGS_ATTRIBUTE_WRITE) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " attribute_write", 16);
                    found = true;
                }
                if (!found) pm_buffer_append_string(output_buffer, " \xe2\x88\x85", 4);
                pm_buffer_append_byte(output_buffer, '\n');
            }

            // receiver
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 receiver:", 19);
                if (cast->receiver == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->receiver, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // call_operator_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 call_operator_loc:", 28);
                pm_location_t *location = &cast->call_operator_loc;
                if (location->start == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, ' ');
                    prettyprint_location(output_buffer, parser, location);
                    pm_buffer_append_string(output_buffer, " = \"", 4);
                    prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                    pm_buffer_append_string(output_buffer, "\"\n", 2);
                }
            }

            // opening_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 opening_loc:", 22);
                pm_location_t *location = &cast->opening_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // arguments
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 arguments:", 20);
                if (cast->arguments == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->arguments, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // closing_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 closing_loc:", 22);
                pm_location_t *location = &cast->closing_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // block
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 block:", 16);
                if (cast->block == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->block, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // operator_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 operator_loc:", 23);
                pm_location_t *location = &cast->operator_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // value
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 value:", 16);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "    ", 4);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            break;
        }
        case PM_INDEX_OPERATOR_WRITE_NODE: {
            pm_index_operator_write_node_t *cast = (pm_index_operator_write_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ IndexOperatorWriteNode (location: ", 36);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // flags
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 flags:", 16);
                bool found = false;
                if (cast->base.flags & PM_CALL_NODE_FLAGS_SAFE_NAVIGATION) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " safe_navigation", 16);
                    found = true;
                }
                if (cast->base.flags & PM_CALL_NODE_FLAGS_VARIABLE_CALL) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " variable_call", 14);
                    found = true;
                }
                if (cast->base.flags & PM_CALL_NODE_FLAGS_ATTRIBUTE_WRITE) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " attribute_write", 16);
                    found = true;
                }
                if (!found) pm_buffer_append_string(output_buffer, " \xe2\x88\x85", 4);
                pm_buffer_append_byte(output_buffer, '\n');
            }

            // receiver
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 receiver:", 19);
                if (cast->receiver == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->receiver, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // call_operator_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 call_operator_loc:", 28);
                pm_location_t *location = &cast->call_operator_loc;
                if (location->start == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, ' ');
                    prettyprint_location(output_buffer, parser, location);
                    pm_buffer_append_string(output_buffer, " = \"", 4);
                    prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                    pm_buffer_append_string(output_buffer, "\"\n", 2);
                }
            }

            // opening_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 opening_loc:", 22);
                pm_location_t *location = &cast->opening_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // arguments
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 arguments:", 20);
                if (cast->arguments == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->arguments, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // closing_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 closing_loc:", 22);
                pm_location_t *location = &cast->closing_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // block
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 block:", 16);
                if (cast->block == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->block, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // operator
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 operator:", 19);
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_constant(output_buffer, parser, cast->operator);
                pm_buffer_append_byte(output_buffer, '\n');
            }

            // operator_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 operator_loc:", 23);
                pm_location_t *location = &cast->operator_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // value
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 value:", 16);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "    ", 4);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            break;
        }
        case PM_INDEX_OR_WRITE_NODE: {
            pm_index_or_write_node_t *cast = (pm_index_or_write_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ IndexOrWriteNode (location: ", 30);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // flags
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 flags:", 16);
                bool found = false;
                if (cast->base.flags & PM_CALL_NODE_FLAGS_SAFE_NAVIGATION) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " safe_navigation", 16);
                    found = true;
                }
                if (cast->base.flags & PM_CALL_NODE_FLAGS_VARIABLE_CALL) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " variable_call", 14);
                    found = true;
                }
                if (cast->base.flags & PM_CALL_NODE_FLAGS_ATTRIBUTE_WRITE) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " attribute_write", 16);
                    found = true;
                }
                if (!found) pm_buffer_append_string(output_buffer, " \xe2\x88\x85", 4);
                pm_buffer_append_byte(output_buffer, '\n');
            }

            // receiver
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 receiver:", 19);
                if (cast->receiver == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->receiver, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // call_operator_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 call_operator_loc:", 28);
                pm_location_t *location = &cast->call_operator_loc;
                if (location->start == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, ' ');
                    prettyprint_location(output_buffer, parser, location);
                    pm_buffer_append_string(output_buffer, " = \"", 4);
                    prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                    pm_buffer_append_string(output_buffer, "\"\n", 2);
                }
            }

            // opening_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 opening_loc:", 22);
                pm_location_t *location = &cast->opening_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // arguments
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 arguments:", 20);
                if (cast->arguments == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->arguments, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // closing_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 closing_loc:", 22);
                pm_location_t *location = &cast->closing_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // block
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 block:", 16);
                if (cast->block == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->block, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // operator_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 operator_loc:", 23);
                pm_location_t *location = &cast->operator_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // value
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 value:", 16);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "    ", 4);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            break;
        }
        case PM_INDEX_TARGET_NODE: {
            pm_index_target_node_t *cast = (pm_index_target_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ IndexTargetNode (location: ", 29);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // flags
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 flags:", 16);
                bool found = false;
                if (cast->base.flags & PM_CALL_NODE_FLAGS_SAFE_NAVIGATION) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " safe_navigation", 16);
                    found = true;
                }
                if (cast->base.flags & PM_CALL_NODE_FLAGS_VARIABLE_CALL) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " variable_call", 14);
                    found = true;
                }
                if (cast->base.flags & PM_CALL_NODE_FLAGS_ATTRIBUTE_WRITE) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " attribute_write", 16);
                    found = true;
                }
                if (!found) pm_buffer_append_string(output_buffer, " \xe2\x88\x85", 4);
                pm_buffer_append_byte(output_buffer, '\n');
            }

            // receiver
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 receiver:", 19);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->receiver, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            // opening_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 opening_loc:", 22);
                pm_location_t *location = &cast->opening_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // arguments
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 arguments:", 20);
                if (cast->arguments == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->arguments, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // closing_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 closing_loc:", 22);
                pm_location_t *location = &cast->closing_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // block
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 block:", 16);
                if (cast->block == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "    ", 4);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->block, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            break;
        }
        case PM_INSTANCE_VARIABLE_AND_WRITE_NODE: {
            pm_instance_variable_and_write_node_t *cast = (pm_instance_variable_and_write_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ InstanceVariableAndWriteNode (location: ", 42);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // name
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 name:", 15);
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_constant(output_buffer, parser, cast->name);
                pm_buffer_append_byte(output_buffer, '\n');
            }

            // name_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 name_loc:", 19);
                pm_location_t *location = &cast->name_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // operator_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 operator_loc:", 23);
                pm_location_t *location = &cast->operator_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // value
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 value:", 16);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "    ", 4);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            break;
        }
        case PM_INSTANCE_VARIABLE_OPERATOR_WRITE_NODE: {
            pm_instance_variable_operator_write_node_t *cast = (pm_instance_variable_operator_write_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ InstanceVariableOperatorWriteNode (location: ", 47);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // name
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 name:", 15);
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_constant(output_buffer, parser, cast->name);
                pm_buffer_append_byte(output_buffer, '\n');
            }

            // name_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 name_loc:", 19);
                pm_location_t *location = &cast->name_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // operator_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 operator_loc:", 23);
                pm_location_t *location = &cast->operator_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // value
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 value:", 16);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            // operator
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 operator:", 19);
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_constant(output_buffer, parser, cast->operator);
                pm_buffer_append_byte(output_buffer, '\n');
            }

            break;
        }
        case PM_INSTANCE_VARIABLE_OR_WRITE_NODE: {
            pm_instance_variable_or_write_node_t *cast = (pm_instance_variable_or_write_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ InstanceVariableOrWriteNode (location: ", 41);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // name
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 name:", 15);
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_constant(output_buffer, parser, cast->name);
                pm_buffer_append_byte(output_buffer, '\n');
            }

            // name_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 name_loc:", 19);
                pm_location_t *location = &cast->name_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // operator_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 operator_loc:", 23);
                pm_location_t *location = &cast->operator_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // value
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 value:", 16);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "    ", 4);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            break;
        }
        case PM_INSTANCE_VARIABLE_READ_NODE: {
            pm_instance_variable_read_node_t *cast = (pm_instance_variable_read_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ InstanceVariableReadNode (location: ", 38);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // name
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 name:", 15);
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_constant(output_buffer, parser, cast->name);
                pm_buffer_append_byte(output_buffer, '\n');
            }

            break;
        }
        case PM_INSTANCE_VARIABLE_TARGET_NODE: {
            pm_instance_variable_target_node_t *cast = (pm_instance_variable_target_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ InstanceVariableTargetNode (location: ", 40);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // name
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 name:", 15);
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_constant(output_buffer, parser, cast->name);
                pm_buffer_append_byte(output_buffer, '\n');
            }

            break;
        }
        case PM_INSTANCE_VARIABLE_WRITE_NODE: {
            pm_instance_variable_write_node_t *cast = (pm_instance_variable_write_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ InstanceVariableWriteNode (location: ", 39);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // name
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 name:", 15);
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_constant(output_buffer, parser, cast->name);
                pm_buffer_append_byte(output_buffer, '\n');
            }

            // name_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 name_loc:", 19);
                pm_location_t *location = &cast->name_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // value
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 value:", 16);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            // operator_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 operator_loc:", 23);
                pm_location_t *location = &cast->operator_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            break;
        }
        case PM_INTEGER_NODE: {
            pm_integer_node_t *cast = (pm_integer_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ IntegerNode (location: ", 25);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // flags
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 flags:", 16);
                bool found = false;
                if (cast->base.flags & PM_INTEGER_BASE_FLAGS_BINARY) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " binary", 7);
                    found = true;
                }
                if (cast->base.flags & PM_INTEGER_BASE_FLAGS_DECIMAL) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " decimal", 8);
                    found = true;
                }
                if (cast->base.flags & PM_INTEGER_BASE_FLAGS_OCTAL) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " octal", 6);
                    found = true;
                }
                if (cast->base.flags & PM_INTEGER_BASE_FLAGS_HEXADECIMAL) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " hexadecimal", 12);
                    found = true;
                }
                if (!found) pm_buffer_append_string(output_buffer, " \xe2\x88\x85", 4);
                pm_buffer_append_byte(output_buffer, '\n');
            }

            break;
        }
        case PM_INTERPOLATED_MATCH_LAST_LINE_NODE: {
            pm_interpolated_match_last_line_node_t *cast = (pm_interpolated_match_last_line_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ InterpolatedMatchLastLineNode (location: ", 43);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // flags
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 flags:", 16);
                bool found = false;
                if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_IGNORE_CASE) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " ignore_case", 12);
                    found = true;
                }
                if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_EXTENDED) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " extended", 9);
                    found = true;
                }
                if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_MULTI_LINE) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " multi_line", 11);
                    found = true;
                }
                if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_ONCE) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " once", 5);
                    found = true;
                }
                if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_EUC_JP) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " euc_jp", 7);
                    found = true;
                }
                if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_ASCII_8BIT) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " ascii_8bit", 11);
                    found = true;
                }
                if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_WINDOWS_31J) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " windows_31j", 12);
                    found = true;
                }
                if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_UTF_8) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " utf_8", 6);
                    found = true;
                }
                if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_FORCED_UTF8_ENCODING) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " forced_utf8_encoding", 21);
                    found = true;
                }
                if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_FORCED_BINARY_ENCODING) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " forced_binary_encoding", 23);
                    found = true;
                }
                if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_FORCED_US_ASCII_ENCODING) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " forced_us_ascii_encoding", 25);
                    found = true;
                }
                if (!found) pm_buffer_append_string(output_buffer, " \xe2\x88\x85", 4);
                pm_buffer_append_byte(output_buffer, '\n');
            }

            // opening_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 opening_loc:", 22);
                pm_location_t *location = &cast->opening_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // parts
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 parts:", 16);
                pm_buffer_append_format(output_buffer, " (length: %lu)\n", (unsigned long) (cast->parts.size));

                size_t last_index = cast->parts.size;
                for (uint32_t index = 0; index < last_index; index++) {
                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);

                    if (index == last_index - 1) {
                        pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 ", 10);
                        pm_buffer_append_string(prefix_buffer, "    ", 4);
                    } else {
                        pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 ", 10);
                        pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    }

                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->parts.nodes[index], prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // closing_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 closing_loc:", 22);
                pm_location_t *location = &cast->closing_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            break;
        }
        case PM_INTERPOLATED_REGULAR_EXPRESSION_NODE: {
            pm_interpolated_regular_expression_node_t *cast = (pm_interpolated_regular_expression_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ InterpolatedRegularExpressionNode (location: ", 47);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // flags
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 flags:", 16);
                bool found = false;
                if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_IGNORE_CASE) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " ignore_case", 12);
                    found = true;
                }
                if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_EXTENDED) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " extended", 9);
                    found = true;
                }
                if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_MULTI_LINE) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " multi_line", 11);
                    found = true;
                }
                if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_ONCE) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " once", 5);
                    found = true;
                }
                if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_EUC_JP) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " euc_jp", 7);
                    found = true;
                }
                if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_ASCII_8BIT) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " ascii_8bit", 11);
                    found = true;
                }
                if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_WINDOWS_31J) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " windows_31j", 12);
                    found = true;
                }
                if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_UTF_8) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " utf_8", 6);
                    found = true;
                }
                if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_FORCED_UTF8_ENCODING) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " forced_utf8_encoding", 21);
                    found = true;
                }
                if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_FORCED_BINARY_ENCODING) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " forced_binary_encoding", 23);
                    found = true;
                }
                if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_FORCED_US_ASCII_ENCODING) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " forced_us_ascii_encoding", 25);
                    found = true;
                }
                if (!found) pm_buffer_append_string(output_buffer, " \xe2\x88\x85", 4);
                pm_buffer_append_byte(output_buffer, '\n');
            }

            // opening_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 opening_loc:", 22);
                pm_location_t *location = &cast->opening_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // parts
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 parts:", 16);
                pm_buffer_append_format(output_buffer, " (length: %lu)\n", (unsigned long) (cast->parts.size));

                size_t last_index = cast->parts.size;
                for (uint32_t index = 0; index < last_index; index++) {
                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);

                    if (index == last_index - 1) {
                        pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 ", 10);
                        pm_buffer_append_string(prefix_buffer, "    ", 4);
                    } else {
                        pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 ", 10);
                        pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    }

                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->parts.nodes[index], prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // closing_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 closing_loc:", 22);
                pm_location_t *location = &cast->closing_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            break;
        }
        case PM_INTERPOLATED_STRING_NODE: {
            pm_interpolated_string_node_t *cast = (pm_interpolated_string_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ InterpolatedStringNode (location: ", 36);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // opening_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 opening_loc:", 22);
                pm_location_t *location = &cast->opening_loc;
                if (location->start == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, ' ');
                    prettyprint_location(output_buffer, parser, location);
                    pm_buffer_append_string(output_buffer, " = \"", 4);
                    prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                    pm_buffer_append_string(output_buffer, "\"\n", 2);
                }
            }

            // parts
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 parts:", 16);
                pm_buffer_append_format(output_buffer, " (length: %lu)\n", (unsigned long) (cast->parts.size));

                size_t last_index = cast->parts.size;
                for (uint32_t index = 0; index < last_index; index++) {
                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);

                    if (index == last_index - 1) {
                        pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 ", 10);
                        pm_buffer_append_string(prefix_buffer, "    ", 4);
                    } else {
                        pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 ", 10);
                        pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    }

                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->parts.nodes[index], prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // closing_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 closing_loc:", 22);
                pm_location_t *location = &cast->closing_loc;
                if (location->start == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, ' ');
                    prettyprint_location(output_buffer, parser, location);
                    pm_buffer_append_string(output_buffer, " = \"", 4);
                    prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                    pm_buffer_append_string(output_buffer, "\"\n", 2);
                }
            }

            break;
        }
        case PM_INTERPOLATED_SYMBOL_NODE: {
            pm_interpolated_symbol_node_t *cast = (pm_interpolated_symbol_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ InterpolatedSymbolNode (location: ", 36);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // opening_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 opening_loc:", 22);
                pm_location_t *location = &cast->opening_loc;
                if (location->start == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, ' ');
                    prettyprint_location(output_buffer, parser, location);
                    pm_buffer_append_string(output_buffer, " = \"", 4);
                    prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                    pm_buffer_append_string(output_buffer, "\"\n", 2);
                }
            }

            // parts
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 parts:", 16);
                pm_buffer_append_format(output_buffer, " (length: %lu)\n", (unsigned long) (cast->parts.size));

                size_t last_index = cast->parts.size;
                for (uint32_t index = 0; index < last_index; index++) {
                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);

                    if (index == last_index - 1) {
                        pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 ", 10);
                        pm_buffer_append_string(prefix_buffer, "    ", 4);
                    } else {
                        pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 ", 10);
                        pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    }

                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->parts.nodes[index], prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // closing_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 closing_loc:", 22);
                pm_location_t *location = &cast->closing_loc;
                if (location->start == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, ' ');
                    prettyprint_location(output_buffer, parser, location);
                    pm_buffer_append_string(output_buffer, " = \"", 4);
                    prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                    pm_buffer_append_string(output_buffer, "\"\n", 2);
                }
            }

            break;
        }
        case PM_INTERPOLATED_X_STRING_NODE: {
            pm_interpolated_x_string_node_t *cast = (pm_interpolated_x_string_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ InterpolatedXStringNode (location: ", 37);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // opening_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 opening_loc:", 22);
                pm_location_t *location = &cast->opening_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // parts
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 parts:", 16);
                pm_buffer_append_format(output_buffer, " (length: %lu)\n", (unsigned long) (cast->parts.size));

                size_t last_index = cast->parts.size;
                for (uint32_t index = 0; index < last_index; index++) {
                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);

                    if (index == last_index - 1) {
                        pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 ", 10);
                        pm_buffer_append_string(prefix_buffer, "    ", 4);
                    } else {
                        pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 ", 10);
                        pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    }

                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->parts.nodes[index], prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // closing_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 closing_loc:", 22);
                pm_location_t *location = &cast->closing_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            break;
        }
        case PM_KEYWORD_HASH_NODE: {
            pm_keyword_hash_node_t *cast = (pm_keyword_hash_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ KeywordHashNode (location: ", 29);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // flags
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 flags:", 16);
                bool found = false;
                if (cast->base.flags & PM_KEYWORD_HASH_NODE_FLAGS_STATIC_KEYS) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " static_keys", 12);
                    found = true;
                }
                if (!found) pm_buffer_append_string(output_buffer, " \xe2\x88\x85", 4);
                pm_buffer_append_byte(output_buffer, '\n');
            }

            // elements
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 elements:", 19);
                pm_buffer_append_format(output_buffer, " (length: %lu)\n", (unsigned long) (cast->elements.size));

                size_t last_index = cast->elements.size;
                for (uint32_t index = 0; index < last_index; index++) {
                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "    ", 4);
                    pm_buffer_concat(output_buffer, prefix_buffer);

                    if (index == last_index - 1) {
                        pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 ", 10);
                        pm_buffer_append_string(prefix_buffer, "    ", 4);
                    } else {
                        pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 ", 10);
                        pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    }

                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->elements.nodes[index], prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            break;
        }
        case PM_KEYWORD_REST_PARAMETER_NODE: {
            pm_keyword_rest_parameter_node_t *cast = (pm_keyword_rest_parameter_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ KeywordRestParameterNode (location: ", 38);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // name
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 name:", 15);
                if (cast->name == 0) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, ' ');
                    prettyprint_constant(output_buffer, parser, cast->name);
                    pm_buffer_append_byte(output_buffer, '\n');
                }
            }

            // name_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 name_loc:", 19);
                pm_location_t *location = &cast->name_loc;
                if (location->start == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, ' ');
                    prettyprint_location(output_buffer, parser, location);
                    pm_buffer_append_string(output_buffer, " = \"", 4);
                    prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                    pm_buffer_append_string(output_buffer, "\"\n", 2);
                }
            }

            // operator_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 operator_loc:", 23);
                pm_location_t *location = &cast->operator_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            break;
        }
        case PM_LAMBDA_NODE: {
            pm_lambda_node_t *cast = (pm_lambda_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ LambdaNode (location: ", 24);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // locals
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 locals:", 17);
                pm_buffer_append_string(output_buffer, " [", 2);
                for (uint32_t index = 0; index < cast->locals.size; index++) {
                    if (index != 0) pm_buffer_append_string(output_buffer, ", ", 2);
                    prettyprint_constant(output_buffer, parser, cast->locals.ids[index]);
                }
                pm_buffer_append_string(output_buffer, "]\n", 2);
            }

            // locals_body_index
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 locals_body_index:", 28);
                pm_buffer_append_format(output_buffer, " %d\n", cast->locals_body_index);
            }

            // operator_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 operator_loc:", 23);
                pm_location_t *location = &cast->operator_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // opening_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 opening_loc:", 22);
                pm_location_t *location = &cast->opening_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // closing_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 closing_loc:", 22);
                pm_location_t *location = &cast->closing_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // parameters
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 parameters:", 21);
                if (cast->parameters == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->parameters, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // body
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 body:", 15);
                if (cast->body == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "    ", 4);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->body, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            break;
        }
        case PM_LOCAL_VARIABLE_AND_WRITE_NODE: {
            pm_local_variable_and_write_node_t *cast = (pm_local_variable_and_write_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ LocalVariableAndWriteNode (location: ", 39);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // name_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 name_loc:", 19);
                pm_location_t *location = &cast->name_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // operator_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 operator_loc:", 23);
                pm_location_t *location = &cast->operator_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // value
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 value:", 16);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            // name
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 name:", 15);
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_constant(output_buffer, parser, cast->name);
                pm_buffer_append_byte(output_buffer, '\n');
            }

            // depth
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 depth:", 16);
                pm_buffer_append_format(output_buffer, " %d\n", cast->depth);
            }

            break;
        }
        case PM_LOCAL_VARIABLE_OPERATOR_WRITE_NODE: {
            pm_local_variable_operator_write_node_t *cast = (pm_local_variable_operator_write_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ LocalVariableOperatorWriteNode (location: ", 44);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // name_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 name_loc:", 19);
                pm_location_t *location = &cast->name_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // operator_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 operator_loc:", 23);
                pm_location_t *location = &cast->operator_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // value
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 value:", 16);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            // name
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 name:", 15);
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_constant(output_buffer, parser, cast->name);
                pm_buffer_append_byte(output_buffer, '\n');
            }

            // operator
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 operator:", 19);
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_constant(output_buffer, parser, cast->operator);
                pm_buffer_append_byte(output_buffer, '\n');
            }

            // depth
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 depth:", 16);
                pm_buffer_append_format(output_buffer, " %d\n", cast->depth);
            }

            break;
        }
        case PM_LOCAL_VARIABLE_OR_WRITE_NODE: {
            pm_local_variable_or_write_node_t *cast = (pm_local_variable_or_write_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ LocalVariableOrWriteNode (location: ", 38);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // name_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 name_loc:", 19);
                pm_location_t *location = &cast->name_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // operator_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 operator_loc:", 23);
                pm_location_t *location = &cast->operator_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // value
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 value:", 16);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            // name
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 name:", 15);
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_constant(output_buffer, parser, cast->name);
                pm_buffer_append_byte(output_buffer, '\n');
            }

            // depth
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 depth:", 16);
                pm_buffer_append_format(output_buffer, " %d\n", cast->depth);
            }

            break;
        }
        case PM_LOCAL_VARIABLE_READ_NODE: {
            pm_local_variable_read_node_t *cast = (pm_local_variable_read_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ LocalVariableReadNode (location: ", 35);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // name
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 name:", 15);
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_constant(output_buffer, parser, cast->name);
                pm_buffer_append_byte(output_buffer, '\n');
            }

            // depth
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 depth:", 16);
                pm_buffer_append_format(output_buffer, " %d\n", cast->depth);
            }

            break;
        }
        case PM_LOCAL_VARIABLE_TARGET_NODE: {
            pm_local_variable_target_node_t *cast = (pm_local_variable_target_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ LocalVariableTargetNode (location: ", 37);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // name
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 name:", 15);
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_constant(output_buffer, parser, cast->name);
                pm_buffer_append_byte(output_buffer, '\n');
            }

            // depth
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 depth:", 16);
                pm_buffer_append_format(output_buffer, " %d\n", cast->depth);
            }

            break;
        }
        case PM_LOCAL_VARIABLE_WRITE_NODE: {
            pm_local_variable_write_node_t *cast = (pm_local_variable_write_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ LocalVariableWriteNode (location: ", 36);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // name
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 name:", 15);
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_constant(output_buffer, parser, cast->name);
                pm_buffer_append_byte(output_buffer, '\n');
            }

            // depth
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 depth:", 16);
                pm_buffer_append_format(output_buffer, " %d\n", cast->depth);
            }

            // name_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 name_loc:", 19);
                pm_location_t *location = &cast->name_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // value
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 value:", 16);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            // operator_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 operator_loc:", 23);
                pm_location_t *location = &cast->operator_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            break;
        }
        case PM_MATCH_LAST_LINE_NODE: {
            pm_match_last_line_node_t *cast = (pm_match_last_line_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ MatchLastLineNode (location: ", 31);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // flags
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 flags:", 16);
                bool found = false;
                if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_IGNORE_CASE) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " ignore_case", 12);
                    found = true;
                }
                if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_EXTENDED) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " extended", 9);
                    found = true;
                }
                if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_MULTI_LINE) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " multi_line", 11);
                    found = true;
                }
                if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_ONCE) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " once", 5);
                    found = true;
                }
                if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_EUC_JP) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " euc_jp", 7);
                    found = true;
                }
                if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_ASCII_8BIT) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " ascii_8bit", 11);
                    found = true;
                }
                if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_WINDOWS_31J) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " windows_31j", 12);
                    found = true;
                }
                if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_UTF_8) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " utf_8", 6);
                    found = true;
                }
                if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_FORCED_UTF8_ENCODING) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " forced_utf8_encoding", 21);
                    found = true;
                }
                if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_FORCED_BINARY_ENCODING) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " forced_binary_encoding", 23);
                    found = true;
                }
                if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_FORCED_US_ASCII_ENCODING) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " forced_us_ascii_encoding", 25);
                    found = true;
                }
                if (!found) pm_buffer_append_string(output_buffer, " \xe2\x88\x85", 4);
                pm_buffer_append_byte(output_buffer, '\n');
            }

            // opening_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 opening_loc:", 22);
                pm_location_t *location = &cast->opening_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // content_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 content_loc:", 22);
                pm_location_t *location = &cast->content_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // closing_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 closing_loc:", 22);
                pm_location_t *location = &cast->closing_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // unescaped
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 unescaped:", 20);
                pm_buffer_append_string(output_buffer, " \"", 2);
                prettyprint_source(output_buffer, pm_string_source(&cast->unescaped), pm_string_length(&cast->unescaped));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            break;
        }
        case PM_MATCH_PREDICATE_NODE: {
            pm_match_predicate_node_t *cast = (pm_match_predicate_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ MatchPredicateNode (location: ", 32);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // value
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 value:", 16);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            // pattern
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 pattern:", 18);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->pattern, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            // operator_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 operator_loc:", 23);
                pm_location_t *location = &cast->operator_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            break;
        }
        case PM_MATCH_REQUIRED_NODE: {
            pm_match_required_node_t *cast = (pm_match_required_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ MatchRequiredNode (location: ", 31);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // value
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 value:", 16);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            // pattern
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 pattern:", 18);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->pattern, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            // operator_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 operator_loc:", 23);
                pm_location_t *location = &cast->operator_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            break;
        }
        case PM_MATCH_WRITE_NODE: {
            pm_match_write_node_t *cast = (pm_match_write_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ MatchWriteNode (location: ", 28);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // call
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 call:", 15);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->call, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            // targets
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 targets:", 18);
                pm_buffer_append_format(output_buffer, " (length: %lu)\n", (unsigned long) (cast->targets.size));

                size_t last_index = cast->targets.size;
                for (uint32_t index = 0; index < last_index; index++) {
                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "    ", 4);
                    pm_buffer_concat(output_buffer, prefix_buffer);

                    if (index == last_index - 1) {
                        pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 ", 10);
                        pm_buffer_append_string(prefix_buffer, "    ", 4);
                    } else {
                        pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 ", 10);
                        pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    }

                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->targets.nodes[index], prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            break;
        }
        case PM_MISSING_NODE: {
            pm_buffer_append_string(output_buffer, "@ MissingNode (location: ", 25);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            break;
        }
        case PM_MODULE_NODE: {
            pm_module_node_t *cast = (pm_module_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ ModuleNode (location: ", 24);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // locals
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 locals:", 17);
                pm_buffer_append_string(output_buffer, " [", 2);
                for (uint32_t index = 0; index < cast->locals.size; index++) {
                    if (index != 0) pm_buffer_append_string(output_buffer, ", ", 2);
                    prettyprint_constant(output_buffer, parser, cast->locals.ids[index]);
                }
                pm_buffer_append_string(output_buffer, "]\n", 2);
            }

            // module_keyword_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 module_keyword_loc:", 29);
                pm_location_t *location = &cast->module_keyword_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // constant_path
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 constant_path:", 24);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->constant_path, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            // body
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 body:", 15);
                if (cast->body == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->body, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // end_keyword_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 end_keyword_loc:", 26);
                pm_location_t *location = &cast->end_keyword_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // name
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 name:", 15);
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_constant(output_buffer, parser, cast->name);
                pm_buffer_append_byte(output_buffer, '\n');
            }

            break;
        }
        case PM_MULTI_TARGET_NODE: {
            pm_multi_target_node_t *cast = (pm_multi_target_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ MultiTargetNode (location: ", 29);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // lefts
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 lefts:", 16);
                pm_buffer_append_format(output_buffer, " (length: %lu)\n", (unsigned long) (cast->lefts.size));

                size_t last_index = cast->lefts.size;
                for (uint32_t index = 0; index < last_index; index++) {
                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);

                    if (index == last_index - 1) {
                        pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 ", 10);
                        pm_buffer_append_string(prefix_buffer, "    ", 4);
                    } else {
                        pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 ", 10);
                        pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    }

                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->lefts.nodes[index], prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // rest
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 rest:", 15);
                if (cast->rest == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->rest, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // rights
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 rights:", 17);
                pm_buffer_append_format(output_buffer, " (length: %lu)\n", (unsigned long) (cast->rights.size));

                size_t last_index = cast->rights.size;
                for (uint32_t index = 0; index < last_index; index++) {
                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);

                    if (index == last_index - 1) {
                        pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 ", 10);
                        pm_buffer_append_string(prefix_buffer, "    ", 4);
                    } else {
                        pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 ", 10);
                        pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    }

                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->rights.nodes[index], prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // lparen_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 lparen_loc:", 21);
                pm_location_t *location = &cast->lparen_loc;
                if (location->start == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, ' ');
                    prettyprint_location(output_buffer, parser, location);
                    pm_buffer_append_string(output_buffer, " = \"", 4);
                    prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                    pm_buffer_append_string(output_buffer, "\"\n", 2);
                }
            }

            // rparen_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 rparen_loc:", 21);
                pm_location_t *location = &cast->rparen_loc;
                if (location->start == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, ' ');
                    prettyprint_location(output_buffer, parser, location);
                    pm_buffer_append_string(output_buffer, " = \"", 4);
                    prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                    pm_buffer_append_string(output_buffer, "\"\n", 2);
                }
            }

            break;
        }
        case PM_MULTI_WRITE_NODE: {
            pm_multi_write_node_t *cast = (pm_multi_write_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ MultiWriteNode (location: ", 28);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // lefts
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 lefts:", 16);
                pm_buffer_append_format(output_buffer, " (length: %lu)\n", (unsigned long) (cast->lefts.size));

                size_t last_index = cast->lefts.size;
                for (uint32_t index = 0; index < last_index; index++) {
                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);

                    if (index == last_index - 1) {
                        pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 ", 10);
                        pm_buffer_append_string(prefix_buffer, "    ", 4);
                    } else {
                        pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 ", 10);
                        pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    }

                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->lefts.nodes[index], prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // rest
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 rest:", 15);
                if (cast->rest == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->rest, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // rights
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 rights:", 17);
                pm_buffer_append_format(output_buffer, " (length: %lu)\n", (unsigned long) (cast->rights.size));

                size_t last_index = cast->rights.size;
                for (uint32_t index = 0; index < last_index; index++) {
                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);

                    if (index == last_index - 1) {
                        pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 ", 10);
                        pm_buffer_append_string(prefix_buffer, "    ", 4);
                    } else {
                        pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 ", 10);
                        pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    }

                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->rights.nodes[index], prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // lparen_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 lparen_loc:", 21);
                pm_location_t *location = &cast->lparen_loc;
                if (location->start == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, ' ');
                    prettyprint_location(output_buffer, parser, location);
                    pm_buffer_append_string(output_buffer, " = \"", 4);
                    prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                    pm_buffer_append_string(output_buffer, "\"\n", 2);
                }
            }

            // rparen_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 rparen_loc:", 21);
                pm_location_t *location = &cast->rparen_loc;
                if (location->start == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, ' ');
                    prettyprint_location(output_buffer, parser, location);
                    pm_buffer_append_string(output_buffer, " = \"", 4);
                    prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                    pm_buffer_append_string(output_buffer, "\"\n", 2);
                }
            }

            // operator_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 operator_loc:", 23);
                pm_location_t *location = &cast->operator_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // value
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 value:", 16);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "    ", 4);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            break;
        }
        case PM_NEXT_NODE: {
            pm_next_node_t *cast = (pm_next_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ NextNode (location: ", 22);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // arguments
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 arguments:", 20);
                if (cast->arguments == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->arguments, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // keyword_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 keyword_loc:", 22);
                pm_location_t *location = &cast->keyword_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            break;
        }
        case PM_NIL_NODE: {
            pm_buffer_append_string(output_buffer, "@ NilNode (location: ", 21);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            break;
        }
        case PM_NO_KEYWORDS_PARAMETER_NODE: {
            pm_no_keywords_parameter_node_t *cast = (pm_no_keywords_parameter_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ NoKeywordsParameterNode (location: ", 37);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // operator_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 operator_loc:", 23);
                pm_location_t *location = &cast->operator_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // keyword_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 keyword_loc:", 22);
                pm_location_t *location = &cast->keyword_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            break;
        }
        case PM_NUMBERED_PARAMETERS_NODE: {
            pm_numbered_parameters_node_t *cast = (pm_numbered_parameters_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ NumberedParametersNode (location: ", 36);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // maximum
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 maximum:", 18);
                pm_buffer_append_format(output_buffer, " %d\n", cast->maximum);
            }

            break;
        }
        case PM_NUMBERED_REFERENCE_READ_NODE: {
            pm_numbered_reference_read_node_t *cast = (pm_numbered_reference_read_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ NumberedReferenceReadNode (location: ", 39);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // number
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 number:", 17);
                pm_buffer_append_format(output_buffer, " %d\n", cast->number);
            }

            break;
        }
        case PM_OPTIONAL_KEYWORD_PARAMETER_NODE: {
            pm_optional_keyword_parameter_node_t *cast = (pm_optional_keyword_parameter_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ OptionalKeywordParameterNode (location: ", 42);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // name
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 name:", 15);
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_constant(output_buffer, parser, cast->name);
                pm_buffer_append_byte(output_buffer, '\n');
            }

            // name_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 name_loc:", 19);
                pm_location_t *location = &cast->name_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // value
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 value:", 16);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "    ", 4);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            break;
        }
        case PM_OPTIONAL_PARAMETER_NODE: {
            pm_optional_parameter_node_t *cast = (pm_optional_parameter_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ OptionalParameterNode (location: ", 35);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // name
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 name:", 15);
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_constant(output_buffer, parser, cast->name);
                pm_buffer_append_byte(output_buffer, '\n');
            }

            // name_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 name_loc:", 19);
                pm_location_t *location = &cast->name_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // operator_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 operator_loc:", 23);
                pm_location_t *location = &cast->operator_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // value
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 value:", 16);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "    ", 4);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            break;
        }
        case PM_OR_NODE: {
            pm_or_node_t *cast = (pm_or_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ OrNode (location: ", 20);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // left
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 left:", 15);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->left, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            // right
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 right:", 16);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->right, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            // operator_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 operator_loc:", 23);
                pm_location_t *location = &cast->operator_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            break;
        }
        case PM_PARAMETERS_NODE: {
            pm_parameters_node_t *cast = (pm_parameters_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ ParametersNode (location: ", 28);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // requireds
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 requireds:", 20);
                pm_buffer_append_format(output_buffer, " (length: %lu)\n", (unsigned long) (cast->requireds.size));

                size_t last_index = cast->requireds.size;
                for (uint32_t index = 0; index < last_index; index++) {
                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);

                    if (index == last_index - 1) {
                        pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 ", 10);
                        pm_buffer_append_string(prefix_buffer, "    ", 4);
                    } else {
                        pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 ", 10);
                        pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    }

                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->requireds.nodes[index], prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // optionals
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 optionals:", 20);
                pm_buffer_append_format(output_buffer, " (length: %lu)\n", (unsigned long) (cast->optionals.size));

                size_t last_index = cast->optionals.size;
                for (uint32_t index = 0; index < last_index; index++) {
                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);

                    if (index == last_index - 1) {
                        pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 ", 10);
                        pm_buffer_append_string(prefix_buffer, "    ", 4);
                    } else {
                        pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 ", 10);
                        pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    }

                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->optionals.nodes[index], prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // rest
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 rest:", 15);
                if (cast->rest == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->rest, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // posts
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 posts:", 16);
                pm_buffer_append_format(output_buffer, " (length: %lu)\n", (unsigned long) (cast->posts.size));

                size_t last_index = cast->posts.size;
                for (uint32_t index = 0; index < last_index; index++) {
                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);

                    if (index == last_index - 1) {
                        pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 ", 10);
                        pm_buffer_append_string(prefix_buffer, "    ", 4);
                    } else {
                        pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 ", 10);
                        pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    }

                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->posts.nodes[index], prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // keywords
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 keywords:", 19);
                pm_buffer_append_format(output_buffer, " (length: %lu)\n", (unsigned long) (cast->keywords.size));

                size_t last_index = cast->keywords.size;
                for (uint32_t index = 0; index < last_index; index++) {
                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);

                    if (index == last_index - 1) {
                        pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 ", 10);
                        pm_buffer_append_string(prefix_buffer, "    ", 4);
                    } else {
                        pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 ", 10);
                        pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    }

                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->keywords.nodes[index], prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // keyword_rest
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 keyword_rest:", 23);
                if (cast->keyword_rest == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->keyword_rest, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // block
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 block:", 16);
                if (cast->block == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "    ", 4);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->block, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            break;
        }
        case PM_PARENTHESES_NODE: {
            pm_parentheses_node_t *cast = (pm_parentheses_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ ParenthesesNode (location: ", 29);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // body
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 body:", 15);
                if (cast->body == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->body, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // opening_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 opening_loc:", 22);
                pm_location_t *location = &cast->opening_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // closing_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 closing_loc:", 22);
                pm_location_t *location = &cast->closing_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            break;
        }
        case PM_PINNED_EXPRESSION_NODE: {
            pm_pinned_expression_node_t *cast = (pm_pinned_expression_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ PinnedExpressionNode (location: ", 34);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // expression
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 expression:", 21);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->expression, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            // operator_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 operator_loc:", 23);
                pm_location_t *location = &cast->operator_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // lparen_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 lparen_loc:", 21);
                pm_location_t *location = &cast->lparen_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // rparen_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 rparen_loc:", 21);
                pm_location_t *location = &cast->rparen_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            break;
        }
        case PM_PINNED_VARIABLE_NODE: {
            pm_pinned_variable_node_t *cast = (pm_pinned_variable_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ PinnedVariableNode (location: ", 32);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // variable
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 variable:", 19);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->variable, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            // operator_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 operator_loc:", 23);
                pm_location_t *location = &cast->operator_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            break;
        }
        case PM_POST_EXECUTION_NODE: {
            pm_post_execution_node_t *cast = (pm_post_execution_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ PostExecutionNode (location: ", 31);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // statements
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 statements:", 21);
                if (cast->statements == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->statements, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // keyword_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 keyword_loc:", 22);
                pm_location_t *location = &cast->keyword_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // opening_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 opening_loc:", 22);
                pm_location_t *location = &cast->opening_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // closing_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 closing_loc:", 22);
                pm_location_t *location = &cast->closing_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            break;
        }
        case PM_PRE_EXECUTION_NODE: {
            pm_pre_execution_node_t *cast = (pm_pre_execution_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ PreExecutionNode (location: ", 30);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // statements
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 statements:", 21);
                if (cast->statements == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->statements, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // keyword_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 keyword_loc:", 22);
                pm_location_t *location = &cast->keyword_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // opening_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 opening_loc:", 22);
                pm_location_t *location = &cast->opening_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // closing_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 closing_loc:", 22);
                pm_location_t *location = &cast->closing_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            break;
        }
        case PM_PROGRAM_NODE: {
            pm_program_node_t *cast = (pm_program_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ ProgramNode (location: ", 25);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // locals
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 locals:", 17);
                pm_buffer_append_string(output_buffer, " [", 2);
                for (uint32_t index = 0; index < cast->locals.size; index++) {
                    if (index != 0) pm_buffer_append_string(output_buffer, ", ", 2);
                    prettyprint_constant(output_buffer, parser, cast->locals.ids[index]);
                }
                pm_buffer_append_string(output_buffer, "]\n", 2);
            }

            // statements
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 statements:", 21);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "    ", 4);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->statements, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            break;
        }
        case PM_RANGE_NODE: {
            pm_range_node_t *cast = (pm_range_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ RangeNode (location: ", 23);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // flags
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 flags:", 16);
                bool found = false;
                if (cast->base.flags & PM_RANGE_FLAGS_EXCLUDE_END) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " exclude_end", 12);
                    found = true;
                }
                if (!found) pm_buffer_append_string(output_buffer, " \xe2\x88\x85", 4);
                pm_buffer_append_byte(output_buffer, '\n');
            }

            // left
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 left:", 15);
                if (cast->left == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->left, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // right
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 right:", 16);
                if (cast->right == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->right, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // operator_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 operator_loc:", 23);
                pm_location_t *location = &cast->operator_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            break;
        }
        case PM_RATIONAL_NODE: {
            pm_rational_node_t *cast = (pm_rational_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ RationalNode (location: ", 26);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // numeric
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 numeric:", 18);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "    ", 4);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->numeric, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            break;
        }
        case PM_REDO_NODE: {
            pm_buffer_append_string(output_buffer, "@ RedoNode (location: ", 22);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            break;
        }
        case PM_REGULAR_EXPRESSION_NODE: {
            pm_regular_expression_node_t *cast = (pm_regular_expression_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ RegularExpressionNode (location: ", 35);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // flags
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 flags:", 16);
                bool found = false;
                if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_IGNORE_CASE) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " ignore_case", 12);
                    found = true;
                }
                if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_EXTENDED) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " extended", 9);
                    found = true;
                }
                if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_MULTI_LINE) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " multi_line", 11);
                    found = true;
                }
                if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_ONCE) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " once", 5);
                    found = true;
                }
                if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_EUC_JP) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " euc_jp", 7);
                    found = true;
                }
                if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_ASCII_8BIT) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " ascii_8bit", 11);
                    found = true;
                }
                if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_WINDOWS_31J) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " windows_31j", 12);
                    found = true;
                }
                if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_UTF_8) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " utf_8", 6);
                    found = true;
                }
                if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_FORCED_UTF8_ENCODING) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " forced_utf8_encoding", 21);
                    found = true;
                }
                if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_FORCED_BINARY_ENCODING) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " forced_binary_encoding", 23);
                    found = true;
                }
                if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_FORCED_US_ASCII_ENCODING) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " forced_us_ascii_encoding", 25);
                    found = true;
                }
                if (!found) pm_buffer_append_string(output_buffer, " \xe2\x88\x85", 4);
                pm_buffer_append_byte(output_buffer, '\n');
            }

            // opening_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 opening_loc:", 22);
                pm_location_t *location = &cast->opening_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // content_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 content_loc:", 22);
                pm_location_t *location = &cast->content_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // closing_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 closing_loc:", 22);
                pm_location_t *location = &cast->closing_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // unescaped
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 unescaped:", 20);
                pm_buffer_append_string(output_buffer, " \"", 2);
                prettyprint_source(output_buffer, pm_string_source(&cast->unescaped), pm_string_length(&cast->unescaped));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            break;
        }
        case PM_REQUIRED_KEYWORD_PARAMETER_NODE: {
            pm_required_keyword_parameter_node_t *cast = (pm_required_keyword_parameter_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ RequiredKeywordParameterNode (location: ", 42);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // name
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 name:", 15);
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_constant(output_buffer, parser, cast->name);
                pm_buffer_append_byte(output_buffer, '\n');
            }

            // name_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 name_loc:", 19);
                pm_location_t *location = &cast->name_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            break;
        }
        case PM_REQUIRED_PARAMETER_NODE: {
            pm_required_parameter_node_t *cast = (pm_required_parameter_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ RequiredParameterNode (location: ", 35);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // name
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 name:", 15);
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_constant(output_buffer, parser, cast->name);
                pm_buffer_append_byte(output_buffer, '\n');
            }

            break;
        }
        case PM_RESCUE_MODIFIER_NODE: {
            pm_rescue_modifier_node_t *cast = (pm_rescue_modifier_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ RescueModifierNode (location: ", 32);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // expression
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 expression:", 21);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->expression, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            // keyword_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 keyword_loc:", 22);
                pm_location_t *location = &cast->keyword_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // rescue_expression
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 rescue_expression:", 28);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "    ", 4);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->rescue_expression, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            break;
        }
        case PM_RESCUE_NODE: {
            pm_rescue_node_t *cast = (pm_rescue_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ RescueNode (location: ", 24);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // keyword_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 keyword_loc:", 22);
                pm_location_t *location = &cast->keyword_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // exceptions
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 exceptions:", 21);
                pm_buffer_append_format(output_buffer, " (length: %lu)\n", (unsigned long) (cast->exceptions.size));

                size_t last_index = cast->exceptions.size;
                for (uint32_t index = 0; index < last_index; index++) {
                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);

                    if (index == last_index - 1) {
                        pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 ", 10);
                        pm_buffer_append_string(prefix_buffer, "    ", 4);
                    } else {
                        pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 ", 10);
                        pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    }

                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->exceptions.nodes[index], prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // operator_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 operator_loc:", 23);
                pm_location_t *location = &cast->operator_loc;
                if (location->start == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, ' ');
                    prettyprint_location(output_buffer, parser, location);
                    pm_buffer_append_string(output_buffer, " = \"", 4);
                    prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                    pm_buffer_append_string(output_buffer, "\"\n", 2);
                }
            }

            // reference
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 reference:", 20);
                if (cast->reference == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->reference, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // statements
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 statements:", 21);
                if (cast->statements == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->statements, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // consequent
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 consequent:", 21);
                if (cast->consequent == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "    ", 4);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->consequent, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            break;
        }
        case PM_REST_PARAMETER_NODE: {
            pm_rest_parameter_node_t *cast = (pm_rest_parameter_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ RestParameterNode (location: ", 31);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // name
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 name:", 15);
                if (cast->name == 0) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, ' ');
                    prettyprint_constant(output_buffer, parser, cast->name);
                    pm_buffer_append_byte(output_buffer, '\n');
                }
            }

            // name_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 name_loc:", 19);
                pm_location_t *location = &cast->name_loc;
                if (location->start == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, ' ');
                    prettyprint_location(output_buffer, parser, location);
                    pm_buffer_append_string(output_buffer, " = \"", 4);
                    prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                    pm_buffer_append_string(output_buffer, "\"\n", 2);
                }
            }

            // operator_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 operator_loc:", 23);
                pm_location_t *location = &cast->operator_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            break;
        }
        case PM_RETRY_NODE: {
            pm_buffer_append_string(output_buffer, "@ RetryNode (location: ", 23);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            break;
        }
        case PM_RETURN_NODE: {
            pm_return_node_t *cast = (pm_return_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ ReturnNode (location: ", 24);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // keyword_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 keyword_loc:", 22);
                pm_location_t *location = &cast->keyword_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // arguments
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 arguments:", 20);
                if (cast->arguments == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "    ", 4);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->arguments, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            break;
        }
        case PM_SELF_NODE: {
            pm_buffer_append_string(output_buffer, "@ SelfNode (location: ", 22);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            break;
        }
        case PM_SINGLETON_CLASS_NODE: {
            pm_singleton_class_node_t *cast = (pm_singleton_class_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ SingletonClassNode (location: ", 32);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // locals
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 locals:", 17);
                pm_buffer_append_string(output_buffer, " [", 2);
                for (uint32_t index = 0; index < cast->locals.size; index++) {
                    if (index != 0) pm_buffer_append_string(output_buffer, ", ", 2);
                    prettyprint_constant(output_buffer, parser, cast->locals.ids[index]);
                }
                pm_buffer_append_string(output_buffer, "]\n", 2);
            }

            // class_keyword_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 class_keyword_loc:", 28);
                pm_location_t *location = &cast->class_keyword_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // operator_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 operator_loc:", 23);
                pm_location_t *location = &cast->operator_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // expression
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 expression:", 21);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->expression, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            // body
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 body:", 15);
                if (cast->body == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->body, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // end_keyword_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 end_keyword_loc:", 26);
                pm_location_t *location = &cast->end_keyword_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            break;
        }
        case PM_SOURCE_ENCODING_NODE: {
            pm_buffer_append_string(output_buffer, "@ SourceEncodingNode (location: ", 32);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            break;
        }
        case PM_SOURCE_FILE_NODE: {
            pm_source_file_node_t *cast = (pm_source_file_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ SourceFileNode (location: ", 28);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // filepath
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 filepath:", 19);
                pm_buffer_append_string(output_buffer, " \"", 2);
                prettyprint_source(output_buffer, pm_string_source(&cast->filepath), pm_string_length(&cast->filepath));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            break;
        }
        case PM_SOURCE_LINE_NODE: {
            pm_buffer_append_string(output_buffer, "@ SourceLineNode (location: ", 28);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            break;
        }
        case PM_SPLAT_NODE: {
            pm_splat_node_t *cast = (pm_splat_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ SplatNode (location: ", 23);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // operator_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 operator_loc:", 23);
                pm_location_t *location = &cast->operator_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // expression
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 expression:", 21);
                if (cast->expression == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "    ", 4);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->expression, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            break;
        }
        case PM_STATEMENTS_NODE: {
            pm_statements_node_t *cast = (pm_statements_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ StatementsNode (location: ", 28);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // body
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 body:", 15);
                pm_buffer_append_format(output_buffer, " (length: %lu)\n", (unsigned long) (cast->body.size));

                size_t last_index = cast->body.size;
                for (uint32_t index = 0; index < last_index; index++) {
                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "    ", 4);
                    pm_buffer_concat(output_buffer, prefix_buffer);

                    if (index == last_index - 1) {
                        pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 ", 10);
                        pm_buffer_append_string(prefix_buffer, "    ", 4);
                    } else {
                        pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 ", 10);
                        pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    }

                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->body.nodes[index], prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            break;
        }
        case PM_STRING_NODE: {
            pm_string_node_t *cast = (pm_string_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ StringNode (location: ", 24);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // flags
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 flags:", 16);
                bool found = false;
                if (cast->base.flags & PM_STRING_FLAGS_FORCED_UTF8_ENCODING) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " forced_utf8_encoding", 21);
                    found = true;
                }
                if (cast->base.flags & PM_STRING_FLAGS_FORCED_BINARY_ENCODING) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " forced_binary_encoding", 23);
                    found = true;
                }
                if (cast->base.flags & PM_STRING_FLAGS_FROZEN) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " frozen", 7);
                    found = true;
                }
                if (!found) pm_buffer_append_string(output_buffer, " \xe2\x88\x85", 4);
                pm_buffer_append_byte(output_buffer, '\n');
            }

            // opening_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 opening_loc:", 22);
                pm_location_t *location = &cast->opening_loc;
                if (location->start == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, ' ');
                    prettyprint_location(output_buffer, parser, location);
                    pm_buffer_append_string(output_buffer, " = \"", 4);
                    prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                    pm_buffer_append_string(output_buffer, "\"\n", 2);
                }
            }

            // content_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 content_loc:", 22);
                pm_location_t *location = &cast->content_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // closing_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 closing_loc:", 22);
                pm_location_t *location = &cast->closing_loc;
                if (location->start == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, ' ');
                    prettyprint_location(output_buffer, parser, location);
                    pm_buffer_append_string(output_buffer, " = \"", 4);
                    prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                    pm_buffer_append_string(output_buffer, "\"\n", 2);
                }
            }

            // unescaped
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 unescaped:", 20);
                pm_buffer_append_string(output_buffer, " \"", 2);
                prettyprint_source(output_buffer, pm_string_source(&cast->unescaped), pm_string_length(&cast->unescaped));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            break;
        }
        case PM_SUPER_NODE: {
            pm_super_node_t *cast = (pm_super_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ SuperNode (location: ", 23);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // keyword_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 keyword_loc:", 22);
                pm_location_t *location = &cast->keyword_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // lparen_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 lparen_loc:", 21);
                pm_location_t *location = &cast->lparen_loc;
                if (location->start == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, ' ');
                    prettyprint_location(output_buffer, parser, location);
                    pm_buffer_append_string(output_buffer, " = \"", 4);
                    prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                    pm_buffer_append_string(output_buffer, "\"\n", 2);
                }
            }

            // arguments
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 arguments:", 20);
                if (cast->arguments == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->arguments, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // rparen_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 rparen_loc:", 21);
                pm_location_t *location = &cast->rparen_loc;
                if (location->start == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, ' ');
                    prettyprint_location(output_buffer, parser, location);
                    pm_buffer_append_string(output_buffer, " = \"", 4);
                    prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                    pm_buffer_append_string(output_buffer, "\"\n", 2);
                }
            }

            // block
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 block:", 16);
                if (cast->block == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "    ", 4);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->block, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            break;
        }
        case PM_SYMBOL_NODE: {
            pm_symbol_node_t *cast = (pm_symbol_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ SymbolNode (location: ", 24);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // flags
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 flags:", 16);
                bool found = false;
                if (cast->base.flags & PM_SYMBOL_FLAGS_FORCED_UTF8_ENCODING) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " forced_utf8_encoding", 21);
                    found = true;
                }
                if (cast->base.flags & PM_SYMBOL_FLAGS_FORCED_BINARY_ENCODING) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " forced_binary_encoding", 23);
                    found = true;
                }
                if (cast->base.flags & PM_SYMBOL_FLAGS_FORCED_US_ASCII_ENCODING) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " forced_us_ascii_encoding", 25);
                    found = true;
                }
                if (!found) pm_buffer_append_string(output_buffer, " \xe2\x88\x85", 4);
                pm_buffer_append_byte(output_buffer, '\n');
            }

            // opening_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 opening_loc:", 22);
                pm_location_t *location = &cast->opening_loc;
                if (location->start == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, ' ');
                    prettyprint_location(output_buffer, parser, location);
                    pm_buffer_append_string(output_buffer, " = \"", 4);
                    prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                    pm_buffer_append_string(output_buffer, "\"\n", 2);
                }
            }

            // value_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 value_loc:", 20);
                pm_location_t *location = &cast->value_loc;
                if (location->start == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, ' ');
                    prettyprint_location(output_buffer, parser, location);
                    pm_buffer_append_string(output_buffer, " = \"", 4);
                    prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                    pm_buffer_append_string(output_buffer, "\"\n", 2);
                }
            }

            // closing_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 closing_loc:", 22);
                pm_location_t *location = &cast->closing_loc;
                if (location->start == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, ' ');
                    prettyprint_location(output_buffer, parser, location);
                    pm_buffer_append_string(output_buffer, " = \"", 4);
                    prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                    pm_buffer_append_string(output_buffer, "\"\n", 2);
                }
            }

            // unescaped
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 unescaped:", 20);
                pm_buffer_append_string(output_buffer, " \"", 2);
                prettyprint_source(output_buffer, pm_string_source(&cast->unescaped), pm_string_length(&cast->unescaped));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            break;
        }
        case PM_TRUE_NODE: {
            pm_buffer_append_string(output_buffer, "@ TrueNode (location: ", 22);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            break;
        }
        case PM_UNDEF_NODE: {
            pm_undef_node_t *cast = (pm_undef_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ UndefNode (location: ", 23);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // names
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 names:", 16);
                pm_buffer_append_format(output_buffer, " (length: %lu)\n", (unsigned long) (cast->names.size));

                size_t last_index = cast->names.size;
                for (uint32_t index = 0; index < last_index; index++) {
                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);

                    if (index == last_index - 1) {
                        pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 ", 10);
                        pm_buffer_append_string(prefix_buffer, "    ", 4);
                    } else {
                        pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 ", 10);
                        pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    }

                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->names.nodes[index], prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // keyword_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 keyword_loc:", 22);
                pm_location_t *location = &cast->keyword_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            break;
        }
        case PM_UNLESS_NODE: {
            pm_unless_node_t *cast = (pm_unless_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ UnlessNode (location: ", 24);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // keyword_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 keyword_loc:", 22);
                pm_location_t *location = &cast->keyword_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // predicate
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 predicate:", 20);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->predicate, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            // then_keyword_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 then_keyword_loc:", 27);
                pm_location_t *location = &cast->then_keyword_loc;
                if (location->start == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, ' ');
                    prettyprint_location(output_buffer, parser, location);
                    pm_buffer_append_string(output_buffer, " = \"", 4);
                    prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                    pm_buffer_append_string(output_buffer, "\"\n", 2);
                }
            }

            // statements
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 statements:", 21);
                if (cast->statements == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->statements, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // consequent
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 consequent:", 21);
                if (cast->consequent == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->consequent, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // end_keyword_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 end_keyword_loc:", 26);
                pm_location_t *location = &cast->end_keyword_loc;
                if (location->start == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, ' ');
                    prettyprint_location(output_buffer, parser, location);
                    pm_buffer_append_string(output_buffer, " = \"", 4);
                    prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                    pm_buffer_append_string(output_buffer, "\"\n", 2);
                }
            }

            break;
        }
        case PM_UNTIL_NODE: {
            pm_until_node_t *cast = (pm_until_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ UntilNode (location: ", 23);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // flags
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 flags:", 16);
                bool found = false;
                if (cast->base.flags & PM_LOOP_FLAGS_BEGIN_MODIFIER) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " begin_modifier", 15);
                    found = true;
                }
                if (!found) pm_buffer_append_string(output_buffer, " \xe2\x88\x85", 4);
                pm_buffer_append_byte(output_buffer, '\n');
            }

            // keyword_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 keyword_loc:", 22);
                pm_location_t *location = &cast->keyword_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // closing_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 closing_loc:", 22);
                pm_location_t *location = &cast->closing_loc;
                if (location->start == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, ' ');
                    prettyprint_location(output_buffer, parser, location);
                    pm_buffer_append_string(output_buffer, " = \"", 4);
                    prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                    pm_buffer_append_string(output_buffer, "\"\n", 2);
                }
            }

            // predicate
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 predicate:", 20);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->predicate, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            // statements
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 statements:", 21);
                if (cast->statements == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "    ", 4);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->statements, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            break;
        }
        case PM_WHEN_NODE: {
            pm_when_node_t *cast = (pm_when_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ WhenNode (location: ", 22);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // keyword_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 keyword_loc:", 22);
                pm_location_t *location = &cast->keyword_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // conditions
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 conditions:", 21);
                pm_buffer_append_format(output_buffer, " (length: %lu)\n", (unsigned long) (cast->conditions.size));

                size_t last_index = cast->conditions.size;
                for (uint32_t index = 0; index < last_index; index++) {
                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);

                    if (index == last_index - 1) {
                        pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 ", 10);
                        pm_buffer_append_string(prefix_buffer, "    ", 4);
                    } else {
                        pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 ", 10);
                        pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    }

                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->conditions.nodes[index], prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // statements
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 statements:", 21);
                if (cast->statements == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "    ", 4);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->statements, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            break;
        }
        case PM_WHILE_NODE: {
            pm_while_node_t *cast = (pm_while_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ WhileNode (location: ", 23);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // flags
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 flags:", 16);
                bool found = false;
                if (cast->base.flags & PM_LOOP_FLAGS_BEGIN_MODIFIER) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " begin_modifier", 15);
                    found = true;
                }
                if (!found) pm_buffer_append_string(output_buffer, " \xe2\x88\x85", 4);
                pm_buffer_append_byte(output_buffer, '\n');
            }

            // keyword_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 keyword_loc:", 22);
                pm_location_t *location = &cast->keyword_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // closing_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 closing_loc:", 22);
                pm_location_t *location = &cast->closing_loc;
                if (location->start == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, ' ');
                    prettyprint_location(output_buffer, parser, location);
                    pm_buffer_append_string(output_buffer, " = \"", 4);
                    prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                    pm_buffer_append_string(output_buffer, "\"\n", 2);
                }
            }

            // predicate
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 predicate:", 20);
                pm_buffer_append_byte(output_buffer, '\n');

                size_t prefix_length = prefix_buffer->length;
                pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                pm_buffer_concat(output_buffer, prefix_buffer);
                prettyprint_node(output_buffer, parser, (pm_node_t *) cast->predicate, prefix_buffer);
                prefix_buffer->length = prefix_length;
            }

            // statements
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 statements:", 21);
                if (cast->statements == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "    ", 4);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->statements, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            break;
        }
        case PM_X_STRING_NODE: {
            pm_x_string_node_t *cast = (pm_x_string_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ XStringNode (location: ", 25);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // flags
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 flags:", 16);
                bool found = false;
                if (cast->base.flags & PM_ENCODING_FLAGS_FORCED_UTF8_ENCODING) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " forced_utf8_encoding", 21);
                    found = true;
                }
                if (cast->base.flags & PM_ENCODING_FLAGS_FORCED_BINARY_ENCODING) {
                    if (found) pm_buffer_append_byte(output_buffer, ',');
                    pm_buffer_append_string(output_buffer, " forced_binary_encoding", 23);
                    found = true;
                }
                if (!found) pm_buffer_append_string(output_buffer, " \xe2\x88\x85", 4);
                pm_buffer_append_byte(output_buffer, '\n');
            }

            // opening_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 opening_loc:", 22);
                pm_location_t *location = &cast->opening_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // content_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 content_loc:", 22);
                pm_location_t *location = &cast->content_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // closing_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 closing_loc:", 22);
                pm_location_t *location = &cast->closing_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // unescaped
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 unescaped:", 20);
                pm_buffer_append_string(output_buffer, " \"", 2);
                prettyprint_source(output_buffer, pm_string_source(&cast->unescaped), pm_string_length(&cast->unescaped));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            break;
        }
        case PM_YIELD_NODE: {
            pm_yield_node_t *cast = (pm_yield_node_t *) node;
            pm_buffer_append_string(output_buffer, "@ YieldNode (location: ", 23);
            prettyprint_location(output_buffer, parser, &node->location);
            pm_buffer_append_string(output_buffer, ")\n", 2);

            // keyword_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 keyword_loc:", 22);
                pm_location_t *location = &cast->keyword_loc;
                pm_buffer_append_byte(output_buffer, ' ');
                prettyprint_location(output_buffer, parser, location);
                pm_buffer_append_string(output_buffer, " = \"", 4);
                prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                pm_buffer_append_string(output_buffer, "\"\n", 2);
            }

            // lparen_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 lparen_loc:", 21);
                pm_location_t *location = &cast->lparen_loc;
                if (location->start == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, ' ');
                    prettyprint_location(output_buffer, parser, location);
                    pm_buffer_append_string(output_buffer, " = \"", 4);
                    prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                    pm_buffer_append_string(output_buffer, "\"\n", 2);
                }
            }

            // arguments
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 arguments:", 20);
                if (cast->arguments == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, '\n');

                    size_t prefix_length = prefix_buffer->length;
                    pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82   ", 6);
                    pm_buffer_concat(output_buffer, prefix_buffer);
                    prettyprint_node(output_buffer, parser, (pm_node_t *) cast->arguments, prefix_buffer);
                    prefix_buffer->length = prefix_length;
                }
            }

            // rparen_loc
            {
                pm_buffer_concat(output_buffer, prefix_buffer);
                pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 rparen_loc:", 21);
                pm_location_t *location = &cast->rparen_loc;
                if (location->start == NULL) {
                    pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
                } else {
                    pm_buffer_append_byte(output_buffer, ' ');
                    prettyprint_location(output_buffer, parser, location);
                    pm_buffer_append_string(output_buffer, " = \"", 4);
                    prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
                    pm_buffer_append_string(output_buffer, "\"\n", 2);
                }
            }

            break;
        }
    }
}

/**
 * Pretty-prints the AST represented by the given node to the given buffer.
 */
PRISM_EXPORTED_FUNCTION void
pm_prettyprint(pm_buffer_t *output_buffer, const pm_parser_t *parser, const pm_node_t *node) {
    pm_buffer_t prefix_buffer = { 0 };
    prettyprint_node(output_buffer, parser, node, &prefix_buffer);
    pm_buffer_free(&prefix_buffer);
}
