// 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/visitor.c.erb

#include <stdio.h>

#include "include/ast/ast_node.h"
#include "include/ast/ast_nodes.h"
#include "include/lib/hb_array.h"
#include "include/visitor.h"

void herb_visit_node(const AST_NODE_T* node, bool (*visitor)(const AST_NODE_T*, void*), void* data) {
  if (visitor(node, data) && node != NULL) {
    herb_visit_child_nodes(node, visitor, data);
  }
}

void herb_visit_child_nodes(const AST_NODE_T *node, bool (*visitor)(const AST_NODE_T *node, void *data), void *data) {
  if (node == NULL) {
    return;
  }

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

      if (document_node->children != NULL) {
        for (size_t index = 0; index < hb_array_size(document_node->children); index++) {
          herb_visit_node(hb_array_get(document_node->children, index), visitor, data);
        }
      }

    } break;

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

      if (html_open_tag_node->children != NULL) {
        for (size_t index = 0; index < hb_array_size(html_open_tag_node->children); index++) {
          herb_visit_node(hb_array_get(html_open_tag_node->children, index), visitor, data);
        }
      }

    } break;

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

      if (html_conditional_open_tag_node->conditional != NULL) {
        herb_visit_node((AST_NODE_T *) html_conditional_open_tag_node->conditional, visitor, data);
      }

    } break;

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

      if (html_close_tag_node->children != NULL) {
        for (size_t index = 0; index < hb_array_size(html_close_tag_node->children); index++) {
          herb_visit_node(hb_array_get(html_close_tag_node->children, index), visitor, data);
        }
      }

    } break;

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

      if (html_element_node->open_tag != NULL) {
        herb_visit_node((AST_NODE_T *) html_element_node->open_tag, visitor, data);
      }

      if (html_element_node->body != NULL) {
        for (size_t index = 0; index < hb_array_size(html_element_node->body); index++) {
          herb_visit_node(hb_array_get(html_element_node->body, index), visitor, data);
        }
      }

      if (html_element_node->close_tag != NULL) {
        herb_visit_node((AST_NODE_T *) html_element_node->close_tag, visitor, data);
      }

    } break;

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

      if (html_conditional_element_node->open_conditional != NULL) {
        herb_visit_node((AST_NODE_T *) html_conditional_element_node->open_conditional, visitor, data);
      }

      if (html_conditional_element_node->open_tag != NULL) {
        herb_visit_node((AST_NODE_T *) html_conditional_element_node->open_tag, visitor, data);
      }

      if (html_conditional_element_node->body != NULL) {
        for (size_t index = 0; index < hb_array_size(html_conditional_element_node->body); index++) {
          herb_visit_node(hb_array_get(html_conditional_element_node->body, index), visitor, data);
        }
      }

      if (html_conditional_element_node->close_tag != NULL) {
        herb_visit_node((AST_NODE_T *) html_conditional_element_node->close_tag, visitor, data);
      }

      if (html_conditional_element_node->close_conditional != NULL) {
        herb_visit_node((AST_NODE_T *) html_conditional_element_node->close_conditional, visitor, data);
      }

    } break;

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

      if (html_attribute_value_node->children != NULL) {
        for (size_t index = 0; index < hb_array_size(html_attribute_value_node->children); index++) {
          herb_visit_node(hb_array_get(html_attribute_value_node->children, index), visitor, data);
        }
      }

    } break;

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

      if (html_attribute_name_node->children != NULL) {
        for (size_t index = 0; index < hb_array_size(html_attribute_name_node->children); index++) {
          herb_visit_node(hb_array_get(html_attribute_name_node->children, index), visitor, data);
        }
      }

    } break;

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

      if (html_attribute_node->name != NULL) {
        herb_visit_node((AST_NODE_T *) html_attribute_node->name, visitor, data);
      }

      if (html_attribute_node->value != NULL) {
        herb_visit_node((AST_NODE_T *) html_attribute_node->value, visitor, data);
      }

    } break;

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

      if (erb_open_tag_node->children != NULL) {
        for (size_t index = 0; index < hb_array_size(erb_open_tag_node->children); index++) {
          herb_visit_node(hb_array_get(erb_open_tag_node->children, index), visitor, data);
        }
      }

    } break;

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

      if (html_comment_node->children != NULL) {
        for (size_t index = 0; index < hb_array_size(html_comment_node->children); index++) {
          herb_visit_node(hb_array_get(html_comment_node->children, index), visitor, data);
        }
      }

    } break;

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

      if (html_doctype_node->children != NULL) {
        for (size_t index = 0; index < hb_array_size(html_doctype_node->children); index++) {
          herb_visit_node(hb_array_get(html_doctype_node->children, index), visitor, data);
        }
      }

    } break;

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

      if (xml_declaration_node->children != NULL) {
        for (size_t index = 0; index < hb_array_size(xml_declaration_node->children); index++) {
          herb_visit_node(hb_array_get(xml_declaration_node->children, index), visitor, data);
        }
      }

    } break;

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

      if (cdata_node->children != NULL) {
        for (size_t index = 0; index < hb_array_size(cdata_node->children); index++) {
          herb_visit_node(hb_array_get(cdata_node->children, index), visitor, data);
        }
      }

    } break;

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

      if (erb_else_node->statements != NULL) {
        for (size_t index = 0; index < hb_array_size(erb_else_node->statements); index++) {
          herb_visit_node(hb_array_get(erb_else_node->statements, index), visitor, data);
        }
      }

    } break;

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

      if (erb_if_node->statements != NULL) {
        for (size_t index = 0; index < hb_array_size(erb_if_node->statements); index++) {
          herb_visit_node(hb_array_get(erb_if_node->statements, index), visitor, data);
        }
      }

      if (erb_if_node->subsequent != NULL) {
        herb_visit_node((AST_NODE_T *) erb_if_node->subsequent, visitor, data);
      }

      if (erb_if_node->end_node != NULL) {
        herb_visit_node((AST_NODE_T *) erb_if_node->end_node, visitor, data);
      }

    } break;

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

      if (erb_block_node->body != NULL) {
        for (size_t index = 0; index < hb_array_size(erb_block_node->body); index++) {
          herb_visit_node(hb_array_get(erb_block_node->body, index), visitor, data);
        }
      }

      if (erb_block_node->rescue_clause != NULL) {
        herb_visit_node((AST_NODE_T *) erb_block_node->rescue_clause, visitor, data);
      }

      if (erb_block_node->else_clause != NULL) {
        herb_visit_node((AST_NODE_T *) erb_block_node->else_clause, visitor, data);
      }

      if (erb_block_node->ensure_clause != NULL) {
        herb_visit_node((AST_NODE_T *) erb_block_node->ensure_clause, visitor, data);
      }

      if (erb_block_node->end_node != NULL) {
        herb_visit_node((AST_NODE_T *) erb_block_node->end_node, visitor, data);
      }

    } break;

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

      if (erb_when_node->statements != NULL) {
        for (size_t index = 0; index < hb_array_size(erb_when_node->statements); index++) {
          herb_visit_node(hb_array_get(erb_when_node->statements, index), visitor, data);
        }
      }

    } break;

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

      if (erb_case_node->children != NULL) {
        for (size_t index = 0; index < hb_array_size(erb_case_node->children); index++) {
          herb_visit_node(hb_array_get(erb_case_node->children, index), visitor, data);
        }
      }

      if (erb_case_node->conditions != NULL) {
        for (size_t index = 0; index < hb_array_size(erb_case_node->conditions); index++) {
          herb_visit_node(hb_array_get(erb_case_node->conditions, index), visitor, data);
        }
      }

      if (erb_case_node->else_clause != NULL) {
        herb_visit_node((AST_NODE_T *) erb_case_node->else_clause, visitor, data);
      }

      if (erb_case_node->end_node != NULL) {
        herb_visit_node((AST_NODE_T *) erb_case_node->end_node, visitor, data);
      }

    } break;

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

      if (erb_case_match_node->children != NULL) {
        for (size_t index = 0; index < hb_array_size(erb_case_match_node->children); index++) {
          herb_visit_node(hb_array_get(erb_case_match_node->children, index), visitor, data);
        }
      }

      if (erb_case_match_node->conditions != NULL) {
        for (size_t index = 0; index < hb_array_size(erb_case_match_node->conditions); index++) {
          herb_visit_node(hb_array_get(erb_case_match_node->conditions, index), visitor, data);
        }
      }

      if (erb_case_match_node->else_clause != NULL) {
        herb_visit_node((AST_NODE_T *) erb_case_match_node->else_clause, visitor, data);
      }

      if (erb_case_match_node->end_node != NULL) {
        herb_visit_node((AST_NODE_T *) erb_case_match_node->end_node, visitor, data);
      }

    } break;

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

      if (erb_while_node->statements != NULL) {
        for (size_t index = 0; index < hb_array_size(erb_while_node->statements); index++) {
          herb_visit_node(hb_array_get(erb_while_node->statements, index), visitor, data);
        }
      }

      if (erb_while_node->end_node != NULL) {
        herb_visit_node((AST_NODE_T *) erb_while_node->end_node, visitor, data);
      }

    } break;

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

      if (erb_until_node->statements != NULL) {
        for (size_t index = 0; index < hb_array_size(erb_until_node->statements); index++) {
          herb_visit_node(hb_array_get(erb_until_node->statements, index), visitor, data);
        }
      }

      if (erb_until_node->end_node != NULL) {
        herb_visit_node((AST_NODE_T *) erb_until_node->end_node, visitor, data);
      }

    } break;

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

      if (erb_for_node->statements != NULL) {
        for (size_t index = 0; index < hb_array_size(erb_for_node->statements); index++) {
          herb_visit_node(hb_array_get(erb_for_node->statements, index), visitor, data);
        }
      }

      if (erb_for_node->end_node != NULL) {
        herb_visit_node((AST_NODE_T *) erb_for_node->end_node, visitor, data);
      }

    } break;

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

      if (erb_rescue_node->statements != NULL) {
        for (size_t index = 0; index < hb_array_size(erb_rescue_node->statements); index++) {
          herb_visit_node(hb_array_get(erb_rescue_node->statements, index), visitor, data);
        }
      }

      if (erb_rescue_node->subsequent != NULL) {
        herb_visit_node((AST_NODE_T *) erb_rescue_node->subsequent, visitor, data);
      }

    } break;

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

      if (erb_ensure_node->statements != NULL) {
        for (size_t index = 0; index < hb_array_size(erb_ensure_node->statements); index++) {
          herb_visit_node(hb_array_get(erb_ensure_node->statements, index), visitor, data);
        }
      }

    } break;

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

      if (erb_begin_node->statements != NULL) {
        for (size_t index = 0; index < hb_array_size(erb_begin_node->statements); index++) {
          herb_visit_node(hb_array_get(erb_begin_node->statements, index), visitor, data);
        }
      }

      if (erb_begin_node->rescue_clause != NULL) {
        herb_visit_node((AST_NODE_T *) erb_begin_node->rescue_clause, visitor, data);
      }

      if (erb_begin_node->else_clause != NULL) {
        herb_visit_node((AST_NODE_T *) erb_begin_node->else_clause, visitor, data);
      }

      if (erb_begin_node->ensure_clause != NULL) {
        herb_visit_node((AST_NODE_T *) erb_begin_node->ensure_clause, visitor, data);
      }

      if (erb_begin_node->end_node != NULL) {
        herb_visit_node((AST_NODE_T *) erb_begin_node->end_node, visitor, data);
      }

    } break;

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

      if (erb_unless_node->statements != NULL) {
        for (size_t index = 0; index < hb_array_size(erb_unless_node->statements); index++) {
          herb_visit_node(hb_array_get(erb_unless_node->statements, index), visitor, data);
        }
      }

      if (erb_unless_node->else_clause != NULL) {
        herb_visit_node((AST_NODE_T *) erb_unless_node->else_clause, visitor, data);
      }

      if (erb_unless_node->end_node != NULL) {
        herb_visit_node((AST_NODE_T *) erb_unless_node->end_node, visitor, data);
      }

    } break;

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

      if (ruby_render_local_node->value != NULL) {
        herb_visit_node((AST_NODE_T *) ruby_render_local_node->value, visitor, data);
      }

    } break;

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

      if (erb_render_node->locals != NULL) {
        for (size_t index = 0; index < hb_array_size(erb_render_node->locals); index++) {
          herb_visit_node(hb_array_get(erb_render_node->locals, index), visitor, data);
        }
      }

    } break;

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

      if (ruby_strict_local_node->default_value != NULL) {
        herb_visit_node((AST_NODE_T *) ruby_strict_local_node->default_value, visitor, data);
      }

    } break;

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

      if (erb_strict_locals_node->locals != NULL) {
        for (size_t index = 0; index < hb_array_size(erb_strict_locals_node->locals); index++) {
          herb_visit_node(hb_array_get(erb_strict_locals_node->locals, index), visitor, data);
        }
      }

    } break;

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

      if (erb_in_node->statements != NULL) {
        for (size_t index = 0; index < hb_array_size(erb_in_node->statements); index++) {
          herb_visit_node(hb_array_get(erb_in_node->statements, index), visitor, data);
        }
      }

    } break;

    default: break;
  }
}
