// NOTE: This file is generated by the templates/template.rb script and should not
// be modified manually. See /home/runner/work/herb/herb/templates/src/ast/ast_pretty_print.c.erb

#ifdef HERB_EXCLUDE_PRETTYPRINT
  // Pretty print support excluded
#else

#include "../include/analyze/helpers.h"
#include "../include/ast/ast_node.h"
#include "../include/ast/ast_nodes.h"
#include "../include/errors.h"
#include "../include/ast/pretty_print.h"
#include "../include/lexer/token_struct.h"
#include "../include/util/util.h"
#include "../include/lib/hb_buffer.h"

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

void ast_pretty_print_node(AST_NODE_T* node, const size_t indent, const size_t relative_indent, hb_buffer_T* buffer) {
  if (!node) { return; }

  bool print_location = true;

  hb_buffer_append(buffer, "@ ");
  hb_buffer_append_string(buffer, ast_node_human_type(node));
  hb_buffer_append(buffer, " ");

  if (print_location) { pretty_print_location(node->location, buffer); }

  hb_buffer_append(buffer, "\n");

  switch (node->type) {
    case AST_DOCUMENT_NODE: {
      const AST_DOCUMENT_NODE_T* document_node = (AST_DOCUMENT_NODE_T*) node;

      pretty_print_errors(node, indent, relative_indent, false, buffer);
      pretty_print_array(hb_string("children"), document_node->children, indent, relative_indent, false, buffer);
      /* prism_context is internal state, not pretty printed */
      if (document_node->prism_node.node != NULL) {
        pretty_print_label(hb_string("prism_node"), indent, relative_indent, true, buffer);
        hb_buffer_append(buffer, " (pm_node_t*)\n");
      }
    } break;

    case AST_LITERAL_NODE: {
      const AST_LITERAL_NODE_T* literal_node = (AST_LITERAL_NODE_T*) node;

      pretty_print_errors(node, indent, relative_indent, false, buffer);
      pretty_print_string_property(literal_node->content, hb_string("content"), indent, relative_indent, true, buffer);
    } break;

    case AST_HTML_OPEN_TAG_NODE: {
      const AST_HTML_OPEN_TAG_NODE_T* html_open_tag_node = (AST_HTML_OPEN_TAG_NODE_T*) node;

      pretty_print_errors(node, indent, relative_indent, false, buffer);
      pretty_print_token_property(html_open_tag_node->tag_opening, hb_string("tag_opening"), indent, relative_indent, false, buffer);
      pretty_print_token_property(html_open_tag_node->tag_name, hb_string("tag_name"), indent, relative_indent, false, buffer);
      pretty_print_token_property(html_open_tag_node->tag_closing, hb_string("tag_closing"), indent, relative_indent, false, buffer);
      pretty_print_array(hb_string("children"), html_open_tag_node->children, indent, relative_indent, false, buffer);
      pretty_print_boolean_property(hb_string("is_void"), html_open_tag_node->is_void, indent, relative_indent, true, buffer);
    } break;

    case AST_HTML_CONDITIONAL_OPEN_TAG_NODE: {
      const AST_HTML_CONDITIONAL_OPEN_TAG_NODE_T* html_conditional_open_tag_node = (AST_HTML_CONDITIONAL_OPEN_TAG_NODE_T*) node;

      pretty_print_errors(node, indent, relative_indent, false, buffer);

      pretty_print_label(hb_string("conditional"), indent, relative_indent, false, buffer);

      if (html_conditional_open_tag_node->conditional) {
        hb_buffer_append(buffer, "\n");
        pretty_print_indent(buffer, indent);
        pretty_print_indent(buffer, relative_indent + 1);

        hb_buffer_append(buffer, "└── ");
        ast_pretty_print_node((AST_NODE_T*) html_conditional_open_tag_node->conditional, indent, relative_indent + 2, buffer);
      } else {
        hb_buffer_append(buffer, " ∅\n");
      }
      hb_buffer_append(buffer, "\n");

      pretty_print_token_property(html_conditional_open_tag_node->tag_name, hb_string("tag_name"), indent, relative_indent, false, buffer);
      pretty_print_boolean_property(hb_string("is_void"), html_conditional_open_tag_node->is_void, indent, relative_indent, true, buffer);
    } break;

    case AST_HTML_CLOSE_TAG_NODE: {
      const AST_HTML_CLOSE_TAG_NODE_T* html_close_tag_node = (AST_HTML_CLOSE_TAG_NODE_T*) node;

      pretty_print_errors(node, indent, relative_indent, false, buffer);
      pretty_print_token_property(html_close_tag_node->tag_opening, hb_string("tag_opening"), indent, relative_indent, false, buffer);
      pretty_print_token_property(html_close_tag_node->tag_name, hb_string("tag_name"), indent, relative_indent, false, buffer);
      pretty_print_array(hb_string("children"), html_close_tag_node->children, indent, relative_indent, false, buffer);
      pretty_print_token_property(html_close_tag_node->tag_closing, hb_string("tag_closing"), indent, relative_indent, true, buffer);
    } break;

    case AST_HTML_OMITTED_CLOSE_TAG_NODE: {
      const AST_HTML_OMITTED_CLOSE_TAG_NODE_T* html_omitted_close_tag_node = (AST_HTML_OMITTED_CLOSE_TAG_NODE_T*) node;

      pretty_print_errors(node, indent, relative_indent, false, buffer);
      pretty_print_token_property(html_omitted_close_tag_node->tag_name, hb_string("tag_name"), indent, relative_indent, true, buffer);
    } break;

    case AST_HTML_VIRTUAL_CLOSE_TAG_NODE: {
      const AST_HTML_VIRTUAL_CLOSE_TAG_NODE_T* html_virtual_close_tag_node = (AST_HTML_VIRTUAL_CLOSE_TAG_NODE_T*) node;

      pretty_print_errors(node, indent, relative_indent, false, buffer);
      pretty_print_token_property(html_virtual_close_tag_node->tag_name, hb_string("tag_name"), indent, relative_indent, true, buffer);
    } break;

    case AST_HTML_ELEMENT_NODE: {
      const AST_HTML_ELEMENT_NODE_T* html_element_node = (AST_HTML_ELEMENT_NODE_T*) node;

      pretty_print_errors(node, indent, relative_indent, false, buffer);

      pretty_print_label(hb_string("open_tag"), indent, relative_indent, false, buffer);

      if (html_element_node->open_tag) {
        hb_buffer_append(buffer, "\n");
        pretty_print_indent(buffer, indent);
        pretty_print_indent(buffer, relative_indent + 1);

        hb_buffer_append(buffer, "└── ");
        ast_pretty_print_node((AST_NODE_T*) html_element_node->open_tag, indent, relative_indent + 2, buffer);
      } else {
        hb_buffer_append(buffer, " ∅\n");
      }
      hb_buffer_append(buffer, "\n");

      pretty_print_token_property(html_element_node->tag_name, hb_string("tag_name"), indent, relative_indent, false, buffer);
      pretty_print_array(hb_string("body"), html_element_node->body, indent, relative_indent, false, buffer);

      pretty_print_label(hb_string("close_tag"), indent, relative_indent, false, buffer);

      if (html_element_node->close_tag) {
        hb_buffer_append(buffer, "\n");
        pretty_print_indent(buffer, indent);
        pretty_print_indent(buffer, relative_indent + 1);

        hb_buffer_append(buffer, "└── ");
        ast_pretty_print_node((AST_NODE_T*) html_element_node->close_tag, indent, relative_indent + 2, buffer);
      } else {
        hb_buffer_append(buffer, " ∅\n");
      }
      hb_buffer_append(buffer, "\n");

      pretty_print_boolean_property(hb_string("is_void"), html_element_node->is_void, indent, relative_indent, false, buffer);
      pretty_print_string_property(html_element_node->element_source, hb_string("element_source"), indent, relative_indent, true, buffer);
    } break;

    case AST_HTML_CONDITIONAL_ELEMENT_NODE: {
      const AST_HTML_CONDITIONAL_ELEMENT_NODE_T* html_conditional_element_node = (AST_HTML_CONDITIONAL_ELEMENT_NODE_T*) node;

      pretty_print_errors(node, indent, relative_indent, false, buffer);
      pretty_print_string_property(html_conditional_element_node->condition, hb_string("condition"), indent, relative_indent, false, buffer);

      pretty_print_label(hb_string("open_conditional"), indent, relative_indent, false, buffer);

      if (html_conditional_element_node->open_conditional) {
        hb_buffer_append(buffer, "\n");
        pretty_print_indent(buffer, indent);
        pretty_print_indent(buffer, relative_indent + 1);

        hb_buffer_append(buffer, "└── ");
        ast_pretty_print_node((AST_NODE_T*) html_conditional_element_node->open_conditional, indent, relative_indent + 2, buffer);
      } else {
        hb_buffer_append(buffer, " ∅\n");
      }
      hb_buffer_append(buffer, "\n");


      pretty_print_label(hb_string("open_tag"), indent, relative_indent, false, buffer);

      if (html_conditional_element_node->open_tag) {
        hb_buffer_append(buffer, "\n");
        pretty_print_indent(buffer, indent);
        pretty_print_indent(buffer, relative_indent + 1);

        hb_buffer_append(buffer, "└── ");
        ast_pretty_print_node((AST_NODE_T*) html_conditional_element_node->open_tag, indent, relative_indent + 2, buffer);
      } else {
        hb_buffer_append(buffer, " ∅\n");
      }
      hb_buffer_append(buffer, "\n");

      pretty_print_array(hb_string("body"), html_conditional_element_node->body, indent, relative_indent, false, buffer);

      pretty_print_label(hb_string("close_tag"), indent, relative_indent, false, buffer);

      if (html_conditional_element_node->close_tag) {
        hb_buffer_append(buffer, "\n");
        pretty_print_indent(buffer, indent);
        pretty_print_indent(buffer, relative_indent + 1);

        hb_buffer_append(buffer, "└── ");
        ast_pretty_print_node((AST_NODE_T*) html_conditional_element_node->close_tag, indent, relative_indent + 2, buffer);
      } else {
        hb_buffer_append(buffer, " ∅\n");
      }
      hb_buffer_append(buffer, "\n");


      pretty_print_label(hb_string("close_conditional"), indent, relative_indent, false, buffer);

      if (html_conditional_element_node->close_conditional) {
        hb_buffer_append(buffer, "\n");
        pretty_print_indent(buffer, indent);
        pretty_print_indent(buffer, relative_indent + 1);

        hb_buffer_append(buffer, "└── ");
        ast_pretty_print_node((AST_NODE_T*) html_conditional_element_node->close_conditional, indent, relative_indent + 2, buffer);
      } else {
        hb_buffer_append(buffer, " ∅\n");
      }
      hb_buffer_append(buffer, "\n");

      pretty_print_token_property(html_conditional_element_node->tag_name, hb_string("tag_name"), indent, relative_indent, false, buffer);
      pretty_print_string_property(html_conditional_element_node->element_source, hb_string("element_source"), indent, relative_indent, true, buffer);
    } break;

    case AST_HTML_ATTRIBUTE_VALUE_NODE: {
      const AST_HTML_ATTRIBUTE_VALUE_NODE_T* html_attribute_value_node = (AST_HTML_ATTRIBUTE_VALUE_NODE_T*) node;

      pretty_print_errors(node, indent, relative_indent, false, buffer);
      pretty_print_token_property(html_attribute_value_node->open_quote, hb_string("open_quote"), indent, relative_indent, false, buffer);
      pretty_print_array(hb_string("children"), html_attribute_value_node->children, indent, relative_indent, false, buffer);
      pretty_print_token_property(html_attribute_value_node->close_quote, hb_string("close_quote"), indent, relative_indent, false, buffer);
      pretty_print_boolean_property(hb_string("quoted"), html_attribute_value_node->quoted, indent, relative_indent, true, buffer);
    } break;

    case AST_HTML_ATTRIBUTE_NAME_NODE: {
      const AST_HTML_ATTRIBUTE_NAME_NODE_T* html_attribute_name_node = (AST_HTML_ATTRIBUTE_NAME_NODE_T*) node;

      pretty_print_errors(node, indent, relative_indent, false, buffer);
      pretty_print_array(hb_string("children"), html_attribute_name_node->children, indent, relative_indent, true, buffer);
    } break;

    case AST_HTML_ATTRIBUTE_NODE: {
      const AST_HTML_ATTRIBUTE_NODE_T* html_attribute_node = (AST_HTML_ATTRIBUTE_NODE_T*) node;

      pretty_print_errors(node, indent, relative_indent, false, buffer);

      pretty_print_label(hb_string("name"), indent, relative_indent, false, buffer);

      if (html_attribute_node->name) {
        hb_buffer_append(buffer, "\n");
        pretty_print_indent(buffer, indent);
        pretty_print_indent(buffer, relative_indent + 1);

        hb_buffer_append(buffer, "└── ");
        ast_pretty_print_node((AST_NODE_T*) html_attribute_node->name, indent, relative_indent + 2, buffer);
      } else {
        hb_buffer_append(buffer, " ∅\n");
      }
      hb_buffer_append(buffer, "\n");

      pretty_print_token_property(html_attribute_node->equals, hb_string("equals"), indent, relative_indent, false, buffer);

      pretty_print_label(hb_string("value"), indent, relative_indent, true, buffer);

      if (html_attribute_node->value) {
        hb_buffer_append(buffer, "\n");
        pretty_print_indent(buffer, indent);
        pretty_print_indent(buffer, relative_indent + 1);

        hb_buffer_append(buffer, "└── ");
        ast_pretty_print_node((AST_NODE_T*) html_attribute_node->value, indent, relative_indent + 2, buffer);
      } else {
        hb_buffer_append(buffer, " ∅\n");
      }
      hb_buffer_append(buffer, "\n");

    } break;

    case AST_RUBY_LITERAL_NODE: {
      const AST_RUBY_LITERAL_NODE_T* ruby_literal_node = (AST_RUBY_LITERAL_NODE_T*) node;

      pretty_print_errors(node, indent, relative_indent, false, buffer);
      pretty_print_string_property(ruby_literal_node->content, hb_string("content"), indent, relative_indent, true, buffer);
    } break;

    case AST_RUBY_HTML_ATTRIBUTES_SPLAT_NODE: {
      const AST_RUBY_HTML_ATTRIBUTES_SPLAT_NODE_T* ruby_html_attributes_splat_node = (AST_RUBY_HTML_ATTRIBUTES_SPLAT_NODE_T*) node;

      pretty_print_errors(node, indent, relative_indent, false, buffer);
      pretty_print_string_property(ruby_html_attributes_splat_node->content, hb_string("content"), indent, relative_indent, false, buffer);
      pretty_print_string_property(ruby_html_attributes_splat_node->prefix, hb_string("prefix"), indent, relative_indent, true, buffer);
    } break;

    case AST_ERB_OPEN_TAG_NODE: {
      const AST_ERB_OPEN_TAG_NODE_T* erb_open_tag_node = (AST_ERB_OPEN_TAG_NODE_T*) node;

      pretty_print_errors(node, indent, relative_indent, false, buffer);
      pretty_print_token_property(erb_open_tag_node->tag_opening, hb_string("tag_opening"), indent, relative_indent, false, buffer);
      pretty_print_token_property(erb_open_tag_node->content, hb_string("content"), indent, relative_indent, false, buffer);
      pretty_print_token_property(erb_open_tag_node->tag_closing, hb_string("tag_closing"), indent, relative_indent, false, buffer);
      pretty_print_token_property(erb_open_tag_node->tag_name, hb_string("tag_name"), indent, relative_indent, false, buffer);
      pretty_print_array(hb_string("children"), erb_open_tag_node->children, indent, relative_indent, true, buffer);
    } break;

    case AST_HTML_TEXT_NODE: {
      const AST_HTML_TEXT_NODE_T* html_text_node = (AST_HTML_TEXT_NODE_T*) node;

      pretty_print_errors(node, indent, relative_indent, false, buffer);
      pretty_print_string_property(html_text_node->content, hb_string("content"), indent, relative_indent, true, buffer);
    } break;

    case AST_HTML_COMMENT_NODE: {
      const AST_HTML_COMMENT_NODE_T* html_comment_node = (AST_HTML_COMMENT_NODE_T*) node;

      pretty_print_errors(node, indent, relative_indent, false, buffer);
      pretty_print_token_property(html_comment_node->comment_start, hb_string("comment_start"), indent, relative_indent, false, buffer);
      pretty_print_array(hb_string("children"), html_comment_node->children, indent, relative_indent, false, buffer);
      pretty_print_token_property(html_comment_node->comment_end, hb_string("comment_end"), indent, relative_indent, true, buffer);
    } break;

    case AST_HTML_DOCTYPE_NODE: {
      const AST_HTML_DOCTYPE_NODE_T* html_doctype_node = (AST_HTML_DOCTYPE_NODE_T*) node;

      pretty_print_errors(node, indent, relative_indent, false, buffer);
      pretty_print_token_property(html_doctype_node->tag_opening, hb_string("tag_opening"), indent, relative_indent, false, buffer);
      pretty_print_array(hb_string("children"), html_doctype_node->children, indent, relative_indent, false, buffer);
      pretty_print_token_property(html_doctype_node->tag_closing, hb_string("tag_closing"), indent, relative_indent, true, buffer);
    } break;

    case AST_XML_DECLARATION_NODE: {
      const AST_XML_DECLARATION_NODE_T* xml_declaration_node = (AST_XML_DECLARATION_NODE_T*) node;

      pretty_print_errors(node, indent, relative_indent, false, buffer);
      pretty_print_token_property(xml_declaration_node->tag_opening, hb_string("tag_opening"), indent, relative_indent, false, buffer);
      pretty_print_array(hb_string("children"), xml_declaration_node->children, indent, relative_indent, false, buffer);
      pretty_print_token_property(xml_declaration_node->tag_closing, hb_string("tag_closing"), indent, relative_indent, true, buffer);
    } break;

    case AST_CDATA_NODE: {
      const AST_CDATA_NODE_T* cdata_node = (AST_CDATA_NODE_T*) node;

      pretty_print_errors(node, indent, relative_indent, false, buffer);
      pretty_print_token_property(cdata_node->tag_opening, hb_string("tag_opening"), indent, relative_indent, false, buffer);
      pretty_print_array(hb_string("children"), cdata_node->children, indent, relative_indent, false, buffer);
      pretty_print_token_property(cdata_node->tag_closing, hb_string("tag_closing"), indent, relative_indent, true, buffer);
    } break;

    case AST_WHITESPACE_NODE: {
      const AST_WHITESPACE_NODE_T* whitespace_node = (AST_WHITESPACE_NODE_T*) node;

      pretty_print_errors(node, indent, relative_indent, false, buffer);
      pretty_print_token_property(whitespace_node->value, hb_string("value"), indent, relative_indent, true, buffer);
    } break;

    case AST_ERB_CONTENT_NODE: {
      const AST_ERB_CONTENT_NODE_T* erb_content_node = (AST_ERB_CONTENT_NODE_T*) node;

      pretty_print_errors(node, indent, relative_indent, false, buffer);
      pretty_print_token_property(erb_content_node->tag_opening, hb_string("tag_opening"), indent, relative_indent, false, buffer);
      pretty_print_token_property(erb_content_node->content, hb_string("content"), indent, relative_indent, false, buffer);
      pretty_print_token_property(erb_content_node->tag_closing, hb_string("tag_closing"), indent, relative_indent, false, buffer);
      if (erb_content_node->analyzed_ruby) {
        pretty_print_boolean_property(hb_string("if_node"), has_if_node(erb_content_node->analyzed_ruby), indent, relative_indent, false, buffer);
        pretty_print_boolean_property(hb_string("elsif_node"), has_elsif_node(erb_content_node->analyzed_ruby), indent, relative_indent, false, buffer);
        pretty_print_boolean_property(hb_string("else_node"), has_else_node(erb_content_node->analyzed_ruby), indent, relative_indent, false, buffer);
        pretty_print_boolean_property(hb_string("end"), has_end(erb_content_node->analyzed_ruby), indent, relative_indent, false, buffer);
        pretty_print_boolean_property(hb_string("block_node"), has_block_node(erb_content_node->analyzed_ruby), indent, relative_indent, false, buffer);
        pretty_print_boolean_property(hb_string("block_closing"), has_block_closing(erb_content_node->analyzed_ruby), indent, relative_indent, false, buffer);
        pretty_print_boolean_property(hb_string("case_node"), has_case_node(erb_content_node->analyzed_ruby), indent, relative_indent, false, buffer);
        pretty_print_boolean_property(hb_string("when_node"), has_when_node(erb_content_node->analyzed_ruby), indent, relative_indent, false, buffer);
        pretty_print_boolean_property(hb_string("for_node"), has_for_node(erb_content_node->analyzed_ruby), indent, relative_indent, false, buffer);
        pretty_print_boolean_property(hb_string("while_node"), has_while_node(erb_content_node->analyzed_ruby), indent, relative_indent, false, buffer);
        pretty_print_boolean_property(hb_string("until_node"), has_until_node(erb_content_node->analyzed_ruby), indent, relative_indent, false, buffer);
        pretty_print_boolean_property(hb_string("begin_node"), has_begin_node(erb_content_node->analyzed_ruby), indent, relative_indent, false, buffer);
        pretty_print_boolean_property(hb_string("rescue_node"), has_rescue_node(erb_content_node->analyzed_ruby), indent, relative_indent, false, buffer);
        pretty_print_boolean_property(hb_string("ensure_node"), has_ensure_node(erb_content_node->analyzed_ruby), indent, relative_indent, false, buffer);
        pretty_print_boolean_property(hb_string("unless_node"), has_unless_node(erb_content_node->analyzed_ruby), indent, relative_indent, false, buffer);
      } else {
      pretty_print_label(hb_string("analyzed_ruby"), indent, relative_indent, false, buffer);
        hb_buffer_append(buffer, " ∅\n");
      }

      pretty_print_boolean_property(hb_string("parsed"), erb_content_node->parsed, indent, relative_indent, false, buffer);
      pretty_print_boolean_property(hb_string("valid"), erb_content_node->valid, indent, relative_indent, false, buffer);
      if (erb_content_node->prism_node.node != NULL) {
        pretty_print_label(hb_string("prism_node"), indent, relative_indent, true, buffer);
        hb_buffer_append(buffer, " (pm_node_t*)\n");
      }
    } break;

    case AST_ERB_END_NODE: {
      const AST_ERB_END_NODE_T* erb_end_node = (AST_ERB_END_NODE_T*) node;

      pretty_print_errors(node, indent, relative_indent, false, buffer);
      pretty_print_token_property(erb_end_node->tag_opening, hb_string("tag_opening"), indent, relative_indent, false, buffer);
      pretty_print_token_property(erb_end_node->content, hb_string("content"), indent, relative_indent, false, buffer);
      pretty_print_token_property(erb_end_node->tag_closing, hb_string("tag_closing"), indent, relative_indent, true, buffer);
    } break;

    case AST_ERB_ELSE_NODE: {
      const AST_ERB_ELSE_NODE_T* erb_else_node = (AST_ERB_ELSE_NODE_T*) node;

      pretty_print_errors(node, indent, relative_indent, false, buffer);
      pretty_print_token_property(erb_else_node->tag_opening, hb_string("tag_opening"), indent, relative_indent, false, buffer);
      pretty_print_token_property(erb_else_node->content, hb_string("content"), indent, relative_indent, false, buffer);
      pretty_print_token_property(erb_else_node->tag_closing, hb_string("tag_closing"), indent, relative_indent, false, buffer);
      pretty_print_array(hb_string("statements"), erb_else_node->statements, indent, relative_indent, true, buffer);
    } break;

    case AST_ERB_IF_NODE: {
      const AST_ERB_IF_NODE_T* erb_if_node = (AST_ERB_IF_NODE_T*) node;

      pretty_print_errors(node, indent, relative_indent, false, buffer);
      pretty_print_token_property(erb_if_node->tag_opening, hb_string("tag_opening"), indent, relative_indent, false, buffer);
      pretty_print_token_property(erb_if_node->content, hb_string("content"), indent, relative_indent, false, buffer);
      pretty_print_token_property(erb_if_node->tag_closing, hb_string("tag_closing"), indent, relative_indent, false, buffer);
      pretty_print_label(hb_string("then_keyword"), indent, relative_indent, false, buffer);
      if (erb_if_node->then_keyword) {
        char then_keyword_location_string[128];
        sprintf(then_keyword_location_string, " (location: (%u:%u)-(%u:%u))\n",
          erb_if_node->then_keyword->start.line,
          erb_if_node->then_keyword->start.column,
          erb_if_node->then_keyword->end.line,
          erb_if_node->then_keyword->end.column);
        hb_buffer_append(buffer, then_keyword_location_string);
      } else {
        hb_buffer_append(buffer, " ∅\n");
      }

      if (erb_if_node->prism_node.node != NULL) {
        pretty_print_label(hb_string("prism_node"), indent, relative_indent, false, buffer);
        hb_buffer_append(buffer, " (pm_node_t*)\n");
      }
      pretty_print_array(hb_string("statements"), erb_if_node->statements, indent, relative_indent, false, buffer);

      pretty_print_label(hb_string("subsequent"), indent, relative_indent, false, buffer);

      if (erb_if_node->subsequent) {
        hb_buffer_append(buffer, "\n");
        pretty_print_indent(buffer, indent);
        pretty_print_indent(buffer, relative_indent + 1);

        hb_buffer_append(buffer, "└── ");
        ast_pretty_print_node((AST_NODE_T*) erb_if_node->subsequent, indent, relative_indent + 2, buffer);
      } else {
        hb_buffer_append(buffer, " ∅\n");
      }
      hb_buffer_append(buffer, "\n");


      pretty_print_label(hb_string("end_node"), indent, relative_indent, true, buffer);

      if (erb_if_node->end_node) {
        hb_buffer_append(buffer, "\n");
        pretty_print_indent(buffer, indent);
        pretty_print_indent(buffer, relative_indent + 1);

        hb_buffer_append(buffer, "└── ");
        ast_pretty_print_node((AST_NODE_T*) erb_if_node->end_node, indent, relative_indent + 2, buffer);
      } else {
        hb_buffer_append(buffer, " ∅\n");
      }
      hb_buffer_append(buffer, "\n");

    } break;

    case AST_ERB_BLOCK_NODE: {
      const AST_ERB_BLOCK_NODE_T* erb_block_node = (AST_ERB_BLOCK_NODE_T*) node;

      pretty_print_errors(node, indent, relative_indent, false, buffer);
      pretty_print_token_property(erb_block_node->tag_opening, hb_string("tag_opening"), indent, relative_indent, false, buffer);
      pretty_print_token_property(erb_block_node->content, hb_string("content"), indent, relative_indent, false, buffer);
      pretty_print_token_property(erb_block_node->tag_closing, hb_string("tag_closing"), indent, relative_indent, false, buffer);
      if (erb_block_node->prism_node.node != NULL) {
        pretty_print_label(hb_string("prism_node"), indent, relative_indent, false, buffer);
        hb_buffer_append(buffer, " (pm_node_t*)\n");
      }
      pretty_print_array(hb_string("body"), erb_block_node->body, indent, relative_indent, false, buffer);

      pretty_print_label(hb_string("rescue_clause"), indent, relative_indent, false, buffer);

      if (erb_block_node->rescue_clause) {
        hb_buffer_append(buffer, "\n");
        pretty_print_indent(buffer, indent);
        pretty_print_indent(buffer, relative_indent + 1);

        hb_buffer_append(buffer, "└── ");
        ast_pretty_print_node((AST_NODE_T*) erb_block_node->rescue_clause, indent, relative_indent + 2, buffer);
      } else {
        hb_buffer_append(buffer, " ∅\n");
      }
      hb_buffer_append(buffer, "\n");


      pretty_print_label(hb_string("else_clause"), indent, relative_indent, false, buffer);

      if (erb_block_node->else_clause) {
        hb_buffer_append(buffer, "\n");
        pretty_print_indent(buffer, indent);
        pretty_print_indent(buffer, relative_indent + 1);

        hb_buffer_append(buffer, "└── ");
        ast_pretty_print_node((AST_NODE_T*) erb_block_node->else_clause, indent, relative_indent + 2, buffer);
      } else {
        hb_buffer_append(buffer, " ∅\n");
      }
      hb_buffer_append(buffer, "\n");


      pretty_print_label(hb_string("ensure_clause"), indent, relative_indent, false, buffer);

      if (erb_block_node->ensure_clause) {
        hb_buffer_append(buffer, "\n");
        pretty_print_indent(buffer, indent);
        pretty_print_indent(buffer, relative_indent + 1);

        hb_buffer_append(buffer, "└── ");
        ast_pretty_print_node((AST_NODE_T*) erb_block_node->ensure_clause, indent, relative_indent + 2, buffer);
      } else {
        hb_buffer_append(buffer, " ∅\n");
      }
      hb_buffer_append(buffer, "\n");


      pretty_print_label(hb_string("end_node"), indent, relative_indent, true, buffer);

      if (erb_block_node->end_node) {
        hb_buffer_append(buffer, "\n");
        pretty_print_indent(buffer, indent);
        pretty_print_indent(buffer, relative_indent + 1);

        hb_buffer_append(buffer, "└── ");
        ast_pretty_print_node((AST_NODE_T*) erb_block_node->end_node, indent, relative_indent + 2, buffer);
      } else {
        hb_buffer_append(buffer, " ∅\n");
      }
      hb_buffer_append(buffer, "\n");

    } break;

    case AST_ERB_WHEN_NODE: {
      const AST_ERB_WHEN_NODE_T* erb_when_node = (AST_ERB_WHEN_NODE_T*) node;

      pretty_print_errors(node, indent, relative_indent, false, buffer);
      pretty_print_token_property(erb_when_node->tag_opening, hb_string("tag_opening"), indent, relative_indent, false, buffer);
      pretty_print_token_property(erb_when_node->content, hb_string("content"), indent, relative_indent, false, buffer);
      pretty_print_token_property(erb_when_node->tag_closing, hb_string("tag_closing"), indent, relative_indent, false, buffer);
      pretty_print_label(hb_string("then_keyword"), indent, relative_indent, false, buffer);
      if (erb_when_node->then_keyword) {
        char then_keyword_location_string[128];
        sprintf(then_keyword_location_string, " (location: (%u:%u)-(%u:%u))\n",
          erb_when_node->then_keyword->start.line,
          erb_when_node->then_keyword->start.column,
          erb_when_node->then_keyword->end.line,
          erb_when_node->then_keyword->end.column);
        hb_buffer_append(buffer, then_keyword_location_string);
      } else {
        hb_buffer_append(buffer, " ∅\n");
      }

      pretty_print_array(hb_string("statements"), erb_when_node->statements, indent, relative_indent, true, buffer);
    } break;

    case AST_ERB_CASE_NODE: {
      const AST_ERB_CASE_NODE_T* erb_case_node = (AST_ERB_CASE_NODE_T*) node;

      pretty_print_errors(node, indent, relative_indent, false, buffer);
      pretty_print_token_property(erb_case_node->tag_opening, hb_string("tag_opening"), indent, relative_indent, false, buffer);
      pretty_print_token_property(erb_case_node->content, hb_string("content"), indent, relative_indent, false, buffer);
      pretty_print_token_property(erb_case_node->tag_closing, hb_string("tag_closing"), indent, relative_indent, false, buffer);
      pretty_print_array(hb_string("children"), erb_case_node->children, indent, relative_indent, false, buffer);
      if (erb_case_node->prism_node.node != NULL) {
        pretty_print_label(hb_string("prism_node"), indent, relative_indent, false, buffer);
        hb_buffer_append(buffer, " (pm_node_t*)\n");
      }
      pretty_print_array(hb_string("conditions"), erb_case_node->conditions, indent, relative_indent, false, buffer);

      pretty_print_label(hb_string("else_clause"), indent, relative_indent, false, buffer);

      if (erb_case_node->else_clause) {
        hb_buffer_append(buffer, "\n");
        pretty_print_indent(buffer, indent);
        pretty_print_indent(buffer, relative_indent + 1);

        hb_buffer_append(buffer, "└── ");
        ast_pretty_print_node((AST_NODE_T*) erb_case_node->else_clause, indent, relative_indent + 2, buffer);
      } else {
        hb_buffer_append(buffer, " ∅\n");
      }
      hb_buffer_append(buffer, "\n");


      pretty_print_label(hb_string("end_node"), indent, relative_indent, true, buffer);

      if (erb_case_node->end_node) {
        hb_buffer_append(buffer, "\n");
        pretty_print_indent(buffer, indent);
        pretty_print_indent(buffer, relative_indent + 1);

        hb_buffer_append(buffer, "└── ");
        ast_pretty_print_node((AST_NODE_T*) erb_case_node->end_node, indent, relative_indent + 2, buffer);
      } else {
        hb_buffer_append(buffer, " ∅\n");
      }
      hb_buffer_append(buffer, "\n");

    } break;

    case AST_ERB_CASE_MATCH_NODE: {
      const AST_ERB_CASE_MATCH_NODE_T* erb_case_match_node = (AST_ERB_CASE_MATCH_NODE_T*) node;

      pretty_print_errors(node, indent, relative_indent, false, buffer);
      pretty_print_token_property(erb_case_match_node->tag_opening, hb_string("tag_opening"), indent, relative_indent, false, buffer);
      pretty_print_token_property(erb_case_match_node->content, hb_string("content"), indent, relative_indent, false, buffer);
      pretty_print_token_property(erb_case_match_node->tag_closing, hb_string("tag_closing"), indent, relative_indent, false, buffer);
      pretty_print_array(hb_string("children"), erb_case_match_node->children, indent, relative_indent, false, buffer);
      if (erb_case_match_node->prism_node.node != NULL) {
        pretty_print_label(hb_string("prism_node"), indent, relative_indent, false, buffer);
        hb_buffer_append(buffer, " (pm_node_t*)\n");
      }
      pretty_print_array(hb_string("conditions"), erb_case_match_node->conditions, indent, relative_indent, false, buffer);

      pretty_print_label(hb_string("else_clause"), indent, relative_indent, false, buffer);

      if (erb_case_match_node->else_clause) {
        hb_buffer_append(buffer, "\n");
        pretty_print_indent(buffer, indent);
        pretty_print_indent(buffer, relative_indent + 1);

        hb_buffer_append(buffer, "└── ");
        ast_pretty_print_node((AST_NODE_T*) erb_case_match_node->else_clause, indent, relative_indent + 2, buffer);
      } else {
        hb_buffer_append(buffer, " ∅\n");
      }
      hb_buffer_append(buffer, "\n");


      pretty_print_label(hb_string("end_node"), indent, relative_indent, true, buffer);

      if (erb_case_match_node->end_node) {
        hb_buffer_append(buffer, "\n");
        pretty_print_indent(buffer, indent);
        pretty_print_indent(buffer, relative_indent + 1);

        hb_buffer_append(buffer, "└── ");
        ast_pretty_print_node((AST_NODE_T*) erb_case_match_node->end_node, indent, relative_indent + 2, buffer);
      } else {
        hb_buffer_append(buffer, " ∅\n");
      }
      hb_buffer_append(buffer, "\n");

    } break;

    case AST_ERB_WHILE_NODE: {
      const AST_ERB_WHILE_NODE_T* erb_while_node = (AST_ERB_WHILE_NODE_T*) node;

      pretty_print_errors(node, indent, relative_indent, false, buffer);
      pretty_print_token_property(erb_while_node->tag_opening, hb_string("tag_opening"), indent, relative_indent, false, buffer);
      pretty_print_token_property(erb_while_node->content, hb_string("content"), indent, relative_indent, false, buffer);
      pretty_print_token_property(erb_while_node->tag_closing, hb_string("tag_closing"), indent, relative_indent, false, buffer);
      if (erb_while_node->prism_node.node != NULL) {
        pretty_print_label(hb_string("prism_node"), indent, relative_indent, false, buffer);
        hb_buffer_append(buffer, " (pm_node_t*)\n");
      }
      pretty_print_array(hb_string("statements"), erb_while_node->statements, indent, relative_indent, false, buffer);

      pretty_print_label(hb_string("end_node"), indent, relative_indent, true, buffer);

      if (erb_while_node->end_node) {
        hb_buffer_append(buffer, "\n");
        pretty_print_indent(buffer, indent);
        pretty_print_indent(buffer, relative_indent + 1);

        hb_buffer_append(buffer, "└── ");
        ast_pretty_print_node((AST_NODE_T*) erb_while_node->end_node, indent, relative_indent + 2, buffer);
      } else {
        hb_buffer_append(buffer, " ∅\n");
      }
      hb_buffer_append(buffer, "\n");

    } break;

    case AST_ERB_UNTIL_NODE: {
      const AST_ERB_UNTIL_NODE_T* erb_until_node = (AST_ERB_UNTIL_NODE_T*) node;

      pretty_print_errors(node, indent, relative_indent, false, buffer);
      pretty_print_token_property(erb_until_node->tag_opening, hb_string("tag_opening"), indent, relative_indent, false, buffer);
      pretty_print_token_property(erb_until_node->content, hb_string("content"), indent, relative_indent, false, buffer);
      pretty_print_token_property(erb_until_node->tag_closing, hb_string("tag_closing"), indent, relative_indent, false, buffer);
      if (erb_until_node->prism_node.node != NULL) {
        pretty_print_label(hb_string("prism_node"), indent, relative_indent, false, buffer);
        hb_buffer_append(buffer, " (pm_node_t*)\n");
      }
      pretty_print_array(hb_string("statements"), erb_until_node->statements, indent, relative_indent, false, buffer);

      pretty_print_label(hb_string("end_node"), indent, relative_indent, true, buffer);

      if (erb_until_node->end_node) {
        hb_buffer_append(buffer, "\n");
        pretty_print_indent(buffer, indent);
        pretty_print_indent(buffer, relative_indent + 1);

        hb_buffer_append(buffer, "└── ");
        ast_pretty_print_node((AST_NODE_T*) erb_until_node->end_node, indent, relative_indent + 2, buffer);
      } else {
        hb_buffer_append(buffer, " ∅\n");
      }
      hb_buffer_append(buffer, "\n");

    } break;

    case AST_ERB_FOR_NODE: {
      const AST_ERB_FOR_NODE_T* erb_for_node = (AST_ERB_FOR_NODE_T*) node;

      pretty_print_errors(node, indent, relative_indent, false, buffer);
      pretty_print_token_property(erb_for_node->tag_opening, hb_string("tag_opening"), indent, relative_indent, false, buffer);
      pretty_print_token_property(erb_for_node->content, hb_string("content"), indent, relative_indent, false, buffer);
      pretty_print_token_property(erb_for_node->tag_closing, hb_string("tag_closing"), indent, relative_indent, false, buffer);
      if (erb_for_node->prism_node.node != NULL) {
        pretty_print_label(hb_string("prism_node"), indent, relative_indent, false, buffer);
        hb_buffer_append(buffer, " (pm_node_t*)\n");
      }
      pretty_print_array(hb_string("statements"), erb_for_node->statements, indent, relative_indent, false, buffer);

      pretty_print_label(hb_string("end_node"), indent, relative_indent, true, buffer);

      if (erb_for_node->end_node) {
        hb_buffer_append(buffer, "\n");
        pretty_print_indent(buffer, indent);
        pretty_print_indent(buffer, relative_indent + 1);

        hb_buffer_append(buffer, "└── ");
        ast_pretty_print_node((AST_NODE_T*) erb_for_node->end_node, indent, relative_indent + 2, buffer);
      } else {
        hb_buffer_append(buffer, " ∅\n");
      }
      hb_buffer_append(buffer, "\n");

    } break;

    case AST_ERB_RESCUE_NODE: {
      const AST_ERB_RESCUE_NODE_T* erb_rescue_node = (AST_ERB_RESCUE_NODE_T*) node;

      pretty_print_errors(node, indent, relative_indent, false, buffer);
      pretty_print_token_property(erb_rescue_node->tag_opening, hb_string("tag_opening"), indent, relative_indent, false, buffer);
      pretty_print_token_property(erb_rescue_node->content, hb_string("content"), indent, relative_indent, false, buffer);
      pretty_print_token_property(erb_rescue_node->tag_closing, hb_string("tag_closing"), indent, relative_indent, false, buffer);
      pretty_print_array(hb_string("statements"), erb_rescue_node->statements, indent, relative_indent, false, buffer);

      pretty_print_label(hb_string("subsequent"), indent, relative_indent, true, buffer);

      if (erb_rescue_node->subsequent) {
        hb_buffer_append(buffer, "\n");
        pretty_print_indent(buffer, indent);
        pretty_print_indent(buffer, relative_indent + 1);

        hb_buffer_append(buffer, "└── ");
        ast_pretty_print_node((AST_NODE_T*) erb_rescue_node->subsequent, indent, relative_indent + 2, buffer);
      } else {
        hb_buffer_append(buffer, " ∅\n");
      }
      hb_buffer_append(buffer, "\n");

    } break;

    case AST_ERB_ENSURE_NODE: {
      const AST_ERB_ENSURE_NODE_T* erb_ensure_node = (AST_ERB_ENSURE_NODE_T*) node;

      pretty_print_errors(node, indent, relative_indent, false, buffer);
      pretty_print_token_property(erb_ensure_node->tag_opening, hb_string("tag_opening"), indent, relative_indent, false, buffer);
      pretty_print_token_property(erb_ensure_node->content, hb_string("content"), indent, relative_indent, false, buffer);
      pretty_print_token_property(erb_ensure_node->tag_closing, hb_string("tag_closing"), indent, relative_indent, false, buffer);
      pretty_print_array(hb_string("statements"), erb_ensure_node->statements, indent, relative_indent, true, buffer);
    } break;

    case AST_ERB_BEGIN_NODE: {
      const AST_ERB_BEGIN_NODE_T* erb_begin_node = (AST_ERB_BEGIN_NODE_T*) node;

      pretty_print_errors(node, indent, relative_indent, false, buffer);
      pretty_print_token_property(erb_begin_node->tag_opening, hb_string("tag_opening"), indent, relative_indent, false, buffer);
      pretty_print_token_property(erb_begin_node->content, hb_string("content"), indent, relative_indent, false, buffer);
      pretty_print_token_property(erb_begin_node->tag_closing, hb_string("tag_closing"), indent, relative_indent, false, buffer);
      if (erb_begin_node->prism_node.node != NULL) {
        pretty_print_label(hb_string("prism_node"), indent, relative_indent, false, buffer);
        hb_buffer_append(buffer, " (pm_node_t*)\n");
      }
      pretty_print_array(hb_string("statements"), erb_begin_node->statements, indent, relative_indent, false, buffer);

      pretty_print_label(hb_string("rescue_clause"), indent, relative_indent, false, buffer);

      if (erb_begin_node->rescue_clause) {
        hb_buffer_append(buffer, "\n");
        pretty_print_indent(buffer, indent);
        pretty_print_indent(buffer, relative_indent + 1);

        hb_buffer_append(buffer, "└── ");
        ast_pretty_print_node((AST_NODE_T*) erb_begin_node->rescue_clause, indent, relative_indent + 2, buffer);
      } else {
        hb_buffer_append(buffer, " ∅\n");
      }
      hb_buffer_append(buffer, "\n");


      pretty_print_label(hb_string("else_clause"), indent, relative_indent, false, buffer);

      if (erb_begin_node->else_clause) {
        hb_buffer_append(buffer, "\n");
        pretty_print_indent(buffer, indent);
        pretty_print_indent(buffer, relative_indent + 1);

        hb_buffer_append(buffer, "└── ");
        ast_pretty_print_node((AST_NODE_T*) erb_begin_node->else_clause, indent, relative_indent + 2, buffer);
      } else {
        hb_buffer_append(buffer, " ∅\n");
      }
      hb_buffer_append(buffer, "\n");


      pretty_print_label(hb_string("ensure_clause"), indent, relative_indent, false, buffer);

      if (erb_begin_node->ensure_clause) {
        hb_buffer_append(buffer, "\n");
        pretty_print_indent(buffer, indent);
        pretty_print_indent(buffer, relative_indent + 1);

        hb_buffer_append(buffer, "└── ");
        ast_pretty_print_node((AST_NODE_T*) erb_begin_node->ensure_clause, indent, relative_indent + 2, buffer);
      } else {
        hb_buffer_append(buffer, " ∅\n");
      }
      hb_buffer_append(buffer, "\n");


      pretty_print_label(hb_string("end_node"), indent, relative_indent, true, buffer);

      if (erb_begin_node->end_node) {
        hb_buffer_append(buffer, "\n");
        pretty_print_indent(buffer, indent);
        pretty_print_indent(buffer, relative_indent + 1);

        hb_buffer_append(buffer, "└── ");
        ast_pretty_print_node((AST_NODE_T*) erb_begin_node->end_node, indent, relative_indent + 2, buffer);
      } else {
        hb_buffer_append(buffer, " ∅\n");
      }
      hb_buffer_append(buffer, "\n");

    } break;

    case AST_ERB_UNLESS_NODE: {
      const AST_ERB_UNLESS_NODE_T* erb_unless_node = (AST_ERB_UNLESS_NODE_T*) node;

      pretty_print_errors(node, indent, relative_indent, false, buffer);
      pretty_print_token_property(erb_unless_node->tag_opening, hb_string("tag_opening"), indent, relative_indent, false, buffer);
      pretty_print_token_property(erb_unless_node->content, hb_string("content"), indent, relative_indent, false, buffer);
      pretty_print_token_property(erb_unless_node->tag_closing, hb_string("tag_closing"), indent, relative_indent, false, buffer);
      pretty_print_label(hb_string("then_keyword"), indent, relative_indent, false, buffer);
      if (erb_unless_node->then_keyword) {
        char then_keyword_location_string[128];
        sprintf(then_keyword_location_string, " (location: (%u:%u)-(%u:%u))\n",
          erb_unless_node->then_keyword->start.line,
          erb_unless_node->then_keyword->start.column,
          erb_unless_node->then_keyword->end.line,
          erb_unless_node->then_keyword->end.column);
        hb_buffer_append(buffer, then_keyword_location_string);
      } else {
        hb_buffer_append(buffer, " ∅\n");
      }

      if (erb_unless_node->prism_node.node != NULL) {
        pretty_print_label(hb_string("prism_node"), indent, relative_indent, false, buffer);
        hb_buffer_append(buffer, " (pm_node_t*)\n");
      }
      pretty_print_array(hb_string("statements"), erb_unless_node->statements, indent, relative_indent, false, buffer);

      pretty_print_label(hb_string("else_clause"), indent, relative_indent, false, buffer);

      if (erb_unless_node->else_clause) {
        hb_buffer_append(buffer, "\n");
        pretty_print_indent(buffer, indent);
        pretty_print_indent(buffer, relative_indent + 1);

        hb_buffer_append(buffer, "└── ");
        ast_pretty_print_node((AST_NODE_T*) erb_unless_node->else_clause, indent, relative_indent + 2, buffer);
      } else {
        hb_buffer_append(buffer, " ∅\n");
      }
      hb_buffer_append(buffer, "\n");


      pretty_print_label(hb_string("end_node"), indent, relative_indent, true, buffer);

      if (erb_unless_node->end_node) {
        hb_buffer_append(buffer, "\n");
        pretty_print_indent(buffer, indent);
        pretty_print_indent(buffer, relative_indent + 1);

        hb_buffer_append(buffer, "└── ");
        ast_pretty_print_node((AST_NODE_T*) erb_unless_node->end_node, indent, relative_indent + 2, buffer);
      } else {
        hb_buffer_append(buffer, " ∅\n");
      }
      hb_buffer_append(buffer, "\n");

    } break;

    case AST_RUBY_RENDER_LOCAL_NODE: {
      const AST_RUBY_RENDER_LOCAL_NODE_T* ruby_render_local_node = (AST_RUBY_RENDER_LOCAL_NODE_T*) node;

      pretty_print_errors(node, indent, relative_indent, false, buffer);
      pretty_print_token_property(ruby_render_local_node->name, hb_string("name"), indent, relative_indent, false, buffer);

      pretty_print_label(hb_string("value"), indent, relative_indent, true, buffer);

      if (ruby_render_local_node->value) {
        hb_buffer_append(buffer, "\n");
        pretty_print_indent(buffer, indent);
        pretty_print_indent(buffer, relative_indent + 1);

        hb_buffer_append(buffer, "└── ");
        ast_pretty_print_node((AST_NODE_T*) ruby_render_local_node->value, indent, relative_indent + 2, buffer);
      } else {
        hb_buffer_append(buffer, " ∅\n");
      }
      hb_buffer_append(buffer, "\n");

    } break;

    case AST_ERB_RENDER_NODE: {
      const AST_ERB_RENDER_NODE_T* erb_render_node = (AST_ERB_RENDER_NODE_T*) node;

      pretty_print_errors(node, indent, relative_indent, false, buffer);
      pretty_print_token_property(erb_render_node->tag_opening, hb_string("tag_opening"), indent, relative_indent, false, buffer);
      pretty_print_token_property(erb_render_node->content, hb_string("content"), indent, relative_indent, false, buffer);
      pretty_print_token_property(erb_render_node->tag_closing, hb_string("tag_closing"), indent, relative_indent, false, buffer);
      if (erb_render_node->analyzed_ruby) {
        pretty_print_boolean_property(hb_string("if_node"), has_if_node(erb_render_node->analyzed_ruby), indent, relative_indent, false, buffer);
        pretty_print_boolean_property(hb_string("elsif_node"), has_elsif_node(erb_render_node->analyzed_ruby), indent, relative_indent, false, buffer);
        pretty_print_boolean_property(hb_string("else_node"), has_else_node(erb_render_node->analyzed_ruby), indent, relative_indent, false, buffer);
        pretty_print_boolean_property(hb_string("end"), has_end(erb_render_node->analyzed_ruby), indent, relative_indent, false, buffer);
        pretty_print_boolean_property(hb_string("block_node"), has_block_node(erb_render_node->analyzed_ruby), indent, relative_indent, false, buffer);
        pretty_print_boolean_property(hb_string("block_closing"), has_block_closing(erb_render_node->analyzed_ruby), indent, relative_indent, false, buffer);
        pretty_print_boolean_property(hb_string("case_node"), has_case_node(erb_render_node->analyzed_ruby), indent, relative_indent, false, buffer);
        pretty_print_boolean_property(hb_string("when_node"), has_when_node(erb_render_node->analyzed_ruby), indent, relative_indent, false, buffer);
        pretty_print_boolean_property(hb_string("for_node"), has_for_node(erb_render_node->analyzed_ruby), indent, relative_indent, false, buffer);
        pretty_print_boolean_property(hb_string("while_node"), has_while_node(erb_render_node->analyzed_ruby), indent, relative_indent, false, buffer);
        pretty_print_boolean_property(hb_string("until_node"), has_until_node(erb_render_node->analyzed_ruby), indent, relative_indent, false, buffer);
        pretty_print_boolean_property(hb_string("begin_node"), has_begin_node(erb_render_node->analyzed_ruby), indent, relative_indent, false, buffer);
        pretty_print_boolean_property(hb_string("rescue_node"), has_rescue_node(erb_render_node->analyzed_ruby), indent, relative_indent, false, buffer);
        pretty_print_boolean_property(hb_string("ensure_node"), has_ensure_node(erb_render_node->analyzed_ruby), indent, relative_indent, false, buffer);
        pretty_print_boolean_property(hb_string("unless_node"), has_unless_node(erb_render_node->analyzed_ruby), indent, relative_indent, false, buffer);
      } else {
      pretty_print_label(hb_string("analyzed_ruby"), indent, relative_indent, false, buffer);
        hb_buffer_append(buffer, " ∅\n");
      }

      if (erb_render_node->prism_node.node != NULL) {
        pretty_print_label(hb_string("prism_node"), indent, relative_indent, false, buffer);
        hb_buffer_append(buffer, " (pm_node_t*)\n");
      }
      pretty_print_token_property(erb_render_node->partial, hb_string("partial"), indent, relative_indent, false, buffer);
      pretty_print_token_property(erb_render_node->template_path, hb_string("template_path"), indent, relative_indent, false, buffer);
      pretty_print_token_property(erb_render_node->layout, hb_string("layout"), indent, relative_indent, false, buffer);
      pretty_print_token_property(erb_render_node->file, hb_string("file"), indent, relative_indent, false, buffer);
      pretty_print_token_property(erb_render_node->inline_template, hb_string("inline_template"), indent, relative_indent, false, buffer);
      pretty_print_token_property(erb_render_node->body, hb_string("body"), indent, relative_indent, false, buffer);
      pretty_print_token_property(erb_render_node->plain, hb_string("plain"), indent, relative_indent, false, buffer);
      pretty_print_token_property(erb_render_node->html, hb_string("html"), indent, relative_indent, false, buffer);
      pretty_print_token_property(erb_render_node->renderable, hb_string("renderable"), indent, relative_indent, false, buffer);
      pretty_print_token_property(erb_render_node->collection, hb_string("collection"), indent, relative_indent, false, buffer);
      pretty_print_token_property(erb_render_node->object, hb_string("object"), indent, relative_indent, false, buffer);
      pretty_print_token_property(erb_render_node->as_name, hb_string("as_name"), indent, relative_indent, false, buffer);
      pretty_print_token_property(erb_render_node->spacer_template, hb_string("spacer_template"), indent, relative_indent, false, buffer);
      pretty_print_token_property(erb_render_node->formats, hb_string("formats"), indent, relative_indent, false, buffer);
      pretty_print_token_property(erb_render_node->variants, hb_string("variants"), indent, relative_indent, false, buffer);
      pretty_print_token_property(erb_render_node->handlers, hb_string("handlers"), indent, relative_indent, false, buffer);
      pretty_print_token_property(erb_render_node->content_type, hb_string("content_type"), indent, relative_indent, false, buffer);
      pretty_print_array(hb_string("locals"), erb_render_node->locals, indent, relative_indent, true, buffer);
    } break;

    case AST_RUBY_STRICT_LOCAL_NODE: {
      const AST_RUBY_STRICT_LOCAL_NODE_T* ruby_strict_local_node = (AST_RUBY_STRICT_LOCAL_NODE_T*) node;

      pretty_print_errors(node, indent, relative_indent, false, buffer);
      pretty_print_token_property(ruby_strict_local_node->name, hb_string("name"), indent, relative_indent, false, buffer);

      pretty_print_label(hb_string("default_value"), indent, relative_indent, false, buffer);

      if (ruby_strict_local_node->default_value) {
        hb_buffer_append(buffer, "\n");
        pretty_print_indent(buffer, indent);
        pretty_print_indent(buffer, relative_indent + 1);

        hb_buffer_append(buffer, "└── ");
        ast_pretty_print_node((AST_NODE_T*) ruby_strict_local_node->default_value, indent, relative_indent + 2, buffer);
      } else {
        hb_buffer_append(buffer, " ∅\n");
      }
      hb_buffer_append(buffer, "\n");

      pretty_print_boolean_property(hb_string("required"), ruby_strict_local_node->required, indent, relative_indent, false, buffer);
      pretty_print_boolean_property(hb_string("double_splat"), ruby_strict_local_node->double_splat, indent, relative_indent, true, buffer);
    } break;

    case AST_ERB_STRICT_LOCALS_NODE: {
      const AST_ERB_STRICT_LOCALS_NODE_T* erb_strict_locals_node = (AST_ERB_STRICT_LOCALS_NODE_T*) node;

      pretty_print_errors(node, indent, relative_indent, false, buffer);
      pretty_print_token_property(erb_strict_locals_node->tag_opening, hb_string("tag_opening"), indent, relative_indent, false, buffer);
      pretty_print_token_property(erb_strict_locals_node->content, hb_string("content"), indent, relative_indent, false, buffer);
      pretty_print_token_property(erb_strict_locals_node->tag_closing, hb_string("tag_closing"), indent, relative_indent, false, buffer);
      if (erb_strict_locals_node->analyzed_ruby) {
        pretty_print_boolean_property(hb_string("if_node"), has_if_node(erb_strict_locals_node->analyzed_ruby), indent, relative_indent, false, buffer);
        pretty_print_boolean_property(hb_string("elsif_node"), has_elsif_node(erb_strict_locals_node->analyzed_ruby), indent, relative_indent, false, buffer);
        pretty_print_boolean_property(hb_string("else_node"), has_else_node(erb_strict_locals_node->analyzed_ruby), indent, relative_indent, false, buffer);
        pretty_print_boolean_property(hb_string("end"), has_end(erb_strict_locals_node->analyzed_ruby), indent, relative_indent, false, buffer);
        pretty_print_boolean_property(hb_string("block_node"), has_block_node(erb_strict_locals_node->analyzed_ruby), indent, relative_indent, false, buffer);
        pretty_print_boolean_property(hb_string("block_closing"), has_block_closing(erb_strict_locals_node->analyzed_ruby), indent, relative_indent, false, buffer);
        pretty_print_boolean_property(hb_string("case_node"), has_case_node(erb_strict_locals_node->analyzed_ruby), indent, relative_indent, false, buffer);
        pretty_print_boolean_property(hb_string("when_node"), has_when_node(erb_strict_locals_node->analyzed_ruby), indent, relative_indent, false, buffer);
        pretty_print_boolean_property(hb_string("for_node"), has_for_node(erb_strict_locals_node->analyzed_ruby), indent, relative_indent, false, buffer);
        pretty_print_boolean_property(hb_string("while_node"), has_while_node(erb_strict_locals_node->analyzed_ruby), indent, relative_indent, false, buffer);
        pretty_print_boolean_property(hb_string("until_node"), has_until_node(erb_strict_locals_node->analyzed_ruby), indent, relative_indent, false, buffer);
        pretty_print_boolean_property(hb_string("begin_node"), has_begin_node(erb_strict_locals_node->analyzed_ruby), indent, relative_indent, false, buffer);
        pretty_print_boolean_property(hb_string("rescue_node"), has_rescue_node(erb_strict_locals_node->analyzed_ruby), indent, relative_indent, false, buffer);
        pretty_print_boolean_property(hb_string("ensure_node"), has_ensure_node(erb_strict_locals_node->analyzed_ruby), indent, relative_indent, false, buffer);
        pretty_print_boolean_property(hb_string("unless_node"), has_unless_node(erb_strict_locals_node->analyzed_ruby), indent, relative_indent, false, buffer);
      } else {
      pretty_print_label(hb_string("analyzed_ruby"), indent, relative_indent, false, buffer);
        hb_buffer_append(buffer, " ∅\n");
      }

      if (erb_strict_locals_node->prism_node.node != NULL) {
        pretty_print_label(hb_string("prism_node"), indent, relative_indent, false, buffer);
        hb_buffer_append(buffer, " (pm_node_t*)\n");
      }
      pretty_print_array(hb_string("locals"), erb_strict_locals_node->locals, indent, relative_indent, true, buffer);
    } break;

    case AST_ERB_YIELD_NODE: {
      const AST_ERB_YIELD_NODE_T* erb_yield_node = (AST_ERB_YIELD_NODE_T*) node;

      pretty_print_errors(node, indent, relative_indent, false, buffer);
      pretty_print_token_property(erb_yield_node->tag_opening, hb_string("tag_opening"), indent, relative_indent, false, buffer);
      pretty_print_token_property(erb_yield_node->content, hb_string("content"), indent, relative_indent, false, buffer);
      pretty_print_token_property(erb_yield_node->tag_closing, hb_string("tag_closing"), indent, relative_indent, true, buffer);
    } break;

    case AST_ERB_IN_NODE: {
      const AST_ERB_IN_NODE_T* erb_in_node = (AST_ERB_IN_NODE_T*) node;

      pretty_print_errors(node, indent, relative_indent, false, buffer);
      pretty_print_token_property(erb_in_node->tag_opening, hb_string("tag_opening"), indent, relative_indent, false, buffer);
      pretty_print_token_property(erb_in_node->content, hb_string("content"), indent, relative_indent, false, buffer);
      pretty_print_token_property(erb_in_node->tag_closing, hb_string("tag_closing"), indent, relative_indent, false, buffer);
      pretty_print_label(hb_string("then_keyword"), indent, relative_indent, false, buffer);
      if (erb_in_node->then_keyword) {
        char then_keyword_location_string[128];
        sprintf(then_keyword_location_string, " (location: (%u:%u)-(%u:%u))\n",
          erb_in_node->then_keyword->start.line,
          erb_in_node->then_keyword->start.column,
          erb_in_node->then_keyword->end.line,
          erb_in_node->then_keyword->end.column);
        hb_buffer_append(buffer, then_keyword_location_string);
      } else {
        hb_buffer_append(buffer, " ∅\n");
      }

      pretty_print_array(hb_string("statements"), erb_in_node->statements, indent, relative_indent, true, buffer);
    } break;

  }
}

#endif
