/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

// @generated by Hermes rustgen
// DO NOT EDIT

use hermes::parser::*;
use super::convert::*;
use crate::ast;

pub unsafe fn cvt_node_ptr<'parser, 'gc>(
  cvt: &mut Converter<'parser>,
  gc: &'gc ast::GCLock,
  n: NodePtr) -> &'gc ast::Node<'gc> {
    let nr = n.as_ref();
    let range = ast::SourceRange {
        file: cvt.file_id,
        start: cvt.cvt_smloc(nr.source_range.start),
        end: ast::SourceLoc::invalid(),
    };

    let res = match nr.kind {
        NodeKind::Empty => {
          let mut template = ast::template::Empty {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::Empty::build_template(gc, template)
        }
        NodeKind::Metadata => {
          let mut template = ast::template::Metadata {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::Metadata::build_template(gc, template)
        }
        NodeKind::Program => {
          let body = cvt_node_list(cvt, gc, hermes_get_Program_body(n));
          let mut template = ast::template::Program {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  body,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::Program::build_template(gc, template)
        }
        NodeKind::FunctionExpression => {
          let id = cvt_node_ptr_opt(cvt, gc, hermes_get_FunctionExpression_id(n));
          let params = cvt_node_list(cvt, gc, hermes_get_FunctionExpression_params(n));
          let body = cvt_node_ptr(cvt, gc, hermes_get_FunctionExpression_body(n));
          let type_parameters = cvt_node_ptr_opt(cvt, gc, hermes_get_FunctionExpression_typeParameters(n));
          let return_type = cvt_node_ptr_opt(cvt, gc, hermes_get_FunctionExpression_returnType(n));
          let predicate = cvt_node_ptr_opt(cvt, gc, hermes_get_FunctionExpression_predicate(n));
          let generator = hermes_get_FunctionExpression_generator(n);
          let is_async = hermes_get_FunctionExpression_async(n);
          let mut template = ast::template::FunctionExpression {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  id,
                  params,
                  body,
                  type_parameters,
                  return_type,
                  predicate,
                  generator,
                  is_async,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::FunctionExpression::build_template(gc, template)
        }
        NodeKind::ArrowFunctionExpression => {
          let id = cvt_node_ptr_opt(cvt, gc, hermes_get_ArrowFunctionExpression_id(n));
          let params = cvt_node_list(cvt, gc, hermes_get_ArrowFunctionExpression_params(n));
          let body = cvt_node_ptr(cvt, gc, hermes_get_ArrowFunctionExpression_body(n));
          let type_parameters = cvt_node_ptr_opt(cvt, gc, hermes_get_ArrowFunctionExpression_typeParameters(n));
          let return_type = cvt_node_ptr_opt(cvt, gc, hermes_get_ArrowFunctionExpression_returnType(n));
          let predicate = cvt_node_ptr_opt(cvt, gc, hermes_get_ArrowFunctionExpression_predicate(n));
          let expression = hermes_get_ArrowFunctionExpression_expression(n);
          let is_async = hermes_get_ArrowFunctionExpression_async(n);
          let mut template = ast::template::ArrowFunctionExpression {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  id,
                  params,
                  body,
                  type_parameters,
                  return_type,
                  predicate,
                  expression,
                  is_async,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::ArrowFunctionExpression::build_template(gc, template)
        }
        NodeKind::FunctionDeclaration => {
          let id = cvt_node_ptr_opt(cvt, gc, hermes_get_FunctionDeclaration_id(n));
          let params = cvt_node_list(cvt, gc, hermes_get_FunctionDeclaration_params(n));
          let body = cvt_node_ptr(cvt, gc, hermes_get_FunctionDeclaration_body(n));
          let type_parameters = cvt_node_ptr_opt(cvt, gc, hermes_get_FunctionDeclaration_typeParameters(n));
          let return_type = cvt_node_ptr_opt(cvt, gc, hermes_get_FunctionDeclaration_returnType(n));
          let predicate = cvt_node_ptr_opt(cvt, gc, hermes_get_FunctionDeclaration_predicate(n));
          let generator = hermes_get_FunctionDeclaration_generator(n);
          let is_async = hermes_get_FunctionDeclaration_async(n);
          let mut template = ast::template::FunctionDeclaration {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  id,
                  params,
                  body,
                  type_parameters,
                  return_type,
                  predicate,
                  generator,
                  is_async,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::FunctionDeclaration::build_template(gc, template)
        }
        NodeKind::ComponentDeclaration => {
          let id = cvt_node_ptr(cvt, gc, hermes_get_ComponentDeclaration_id(n));
          let params = cvt_node_list(cvt, gc, hermes_get_ComponentDeclaration_params(n));
          let body = cvt_node_ptr(cvt, gc, hermes_get_ComponentDeclaration_body(n));
          let type_parameters = cvt_node_ptr_opt(cvt, gc, hermes_get_ComponentDeclaration_typeParameters(n));
          let renders_type = cvt_node_ptr_opt(cvt, gc, hermes_get_ComponentDeclaration_rendersType(n));
          let mut template = ast::template::ComponentDeclaration {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  id,
                  params,
                  body,
                  type_parameters,
                  renders_type,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::ComponentDeclaration::build_template(gc, template)
        }
        NodeKind::WhileStatement => {
          let body = cvt_node_ptr(cvt, gc, hermes_get_WhileStatement_body(n));
          let test = cvt_node_ptr(cvt, gc, hermes_get_WhileStatement_test(n));
          let mut template = ast::template::WhileStatement {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  body,
                  test,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::WhileStatement::build_template(gc, template)
        }
        NodeKind::DoWhileStatement => {
          let body = cvt_node_ptr(cvt, gc, hermes_get_DoWhileStatement_body(n));
          let test = cvt_node_ptr(cvt, gc, hermes_get_DoWhileStatement_test(n));
          let mut template = ast::template::DoWhileStatement {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  body,
                  test,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::DoWhileStatement::build_template(gc, template)
        }
        NodeKind::ForInStatement => {
          let left = cvt_node_ptr(cvt, gc, hermes_get_ForInStatement_left(n));
          let right = cvt_node_ptr(cvt, gc, hermes_get_ForInStatement_right(n));
          let body = cvt_node_ptr(cvt, gc, hermes_get_ForInStatement_body(n));
          let mut template = ast::template::ForInStatement {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  left,
                  right,
                  body,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::ForInStatement::build_template(gc, template)
        }
        NodeKind::ForOfStatement => {
          let left = cvt_node_ptr(cvt, gc, hermes_get_ForOfStatement_left(n));
          let right = cvt_node_ptr(cvt, gc, hermes_get_ForOfStatement_right(n));
          let body = cvt_node_ptr(cvt, gc, hermes_get_ForOfStatement_body(n));
          let is_await = hermes_get_ForOfStatement_await(n);
          let mut template = ast::template::ForOfStatement {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  left,
                  right,
                  body,
                  is_await,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::ForOfStatement::build_template(gc, template)
        }
        NodeKind::ForStatement => {
          let init = cvt_node_ptr_opt(cvt, gc, hermes_get_ForStatement_init(n));
          let test = cvt_node_ptr_opt(cvt, gc, hermes_get_ForStatement_test(n));
          let update = cvt_node_ptr_opt(cvt, gc, hermes_get_ForStatement_update(n));
          let body = cvt_node_ptr(cvt, gc, hermes_get_ForStatement_body(n));
          let mut template = ast::template::ForStatement {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  init,
                  test,
                  update,
                  body,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::ForStatement::build_template(gc, template)
        }
        NodeKind::DebuggerStatement => {
          let mut template = ast::template::DebuggerStatement {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::DebuggerStatement::build_template(gc, template)
        }
        NodeKind::EmptyStatement => {
          let mut template = ast::template::EmptyStatement {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::EmptyStatement::build_template(gc, template)
        }
        NodeKind::BlockStatement => {
          let body = cvt_node_list(cvt, gc, hermes_get_BlockStatement_body(n));
          let mut template = ast::template::BlockStatement {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  body,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::BlockStatement::build_template(gc, template)
        }
        NodeKind::BreakStatement => {
          let label = cvt_node_ptr_opt(cvt, gc, hermes_get_BreakStatement_label(n));
          let mut template = ast::template::BreakStatement {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  label,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::BreakStatement::build_template(gc, template)
        }
        NodeKind::ContinueStatement => {
          let label = cvt_node_ptr_opt(cvt, gc, hermes_get_ContinueStatement_label(n));
          let mut template = ast::template::ContinueStatement {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  label,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::ContinueStatement::build_template(gc, template)
        }
        NodeKind::ThrowStatement => {
          let argument = cvt_node_ptr(cvt, gc, hermes_get_ThrowStatement_argument(n));
          let mut template = ast::template::ThrowStatement {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  argument,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::ThrowStatement::build_template(gc, template)
        }
        NodeKind::ReturnStatement => {
          let argument = cvt_node_ptr_opt(cvt, gc, hermes_get_ReturnStatement_argument(n));
          let mut template = ast::template::ReturnStatement {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  argument,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::ReturnStatement::build_template(gc, template)
        }
        NodeKind::WithStatement => {
          let object = cvt_node_ptr(cvt, gc, hermes_get_WithStatement_object(n));
          let body = cvt_node_ptr(cvt, gc, hermes_get_WithStatement_body(n));
          let mut template = ast::template::WithStatement {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  object,
                  body,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::WithStatement::build_template(gc, template)
        }
        NodeKind::SwitchStatement => {
          let discriminant = cvt_node_ptr(cvt, gc, hermes_get_SwitchStatement_discriminant(n));
          let cases = cvt_node_list(cvt, gc, hermes_get_SwitchStatement_cases(n));
          let mut template = ast::template::SwitchStatement {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  discriminant,
                  cases,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::SwitchStatement::build_template(gc, template)
        }
        NodeKind::LabeledStatement => {
          let label = cvt_node_ptr(cvt, gc, hermes_get_LabeledStatement_label(n));
          let body = cvt_node_ptr(cvt, gc, hermes_get_LabeledStatement_body(n));
          let mut template = ast::template::LabeledStatement {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  label,
                  body,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::LabeledStatement::build_template(gc, template)
        }
        NodeKind::ExpressionStatement => {
          let expression = cvt_node_ptr(cvt, gc, hermes_get_ExpressionStatement_expression(n));
          let directive = cvt.cvt_string_opt(gc, hermes_get_ExpressionStatement_directive(n));
          let mut template = ast::template::ExpressionStatement {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  expression,
                  directive,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::ExpressionStatement::build_template(gc, template)
        }
        NodeKind::TryStatement => {
          let block = cvt_node_ptr(cvt, gc, hermes_get_TryStatement_block(n));
          let handler = cvt_node_ptr_opt(cvt, gc, hermes_get_TryStatement_handler(n));
          let finalizer = cvt_node_ptr_opt(cvt, gc, hermes_get_TryStatement_finalizer(n));
          let mut template = ast::template::TryStatement {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  block,
                  handler,
                  finalizer,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::TryStatement::build_template(gc, template)
        }
        NodeKind::IfStatement => {
          let test = cvt_node_ptr(cvt, gc, hermes_get_IfStatement_test(n));
          let consequent = cvt_node_ptr(cvt, gc, hermes_get_IfStatement_consequent(n));
          let alternate = cvt_node_ptr_opt(cvt, gc, hermes_get_IfStatement_alternate(n));
          let mut template = ast::template::IfStatement {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  test,
                  consequent,
                  alternate,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::IfStatement::build_template(gc, template)
        }
        NodeKind::NullLiteral => {
          let mut template = ast::template::NullLiteral {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::NullLiteral::build_template(gc, template)
        }
        NodeKind::BooleanLiteral => {
          let value = hermes_get_BooleanLiteral_value(n);
          let mut template = ast::template::BooleanLiteral {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  value,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::BooleanLiteral::build_template(gc, template)
        }
        NodeKind::StringLiteral => {
          let value = cvt.cvt_string(gc, hermes_get_StringLiteral_value(n));
          let mut template = ast::template::StringLiteral {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  value,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::StringLiteral::build_template(gc, template)
        }
        NodeKind::NumericLiteral => {
          let value = hermes_get_NumericLiteral_value(n);
          let mut template = ast::template::NumericLiteral {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  value,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::NumericLiteral::build_template(gc, template)
        }
        NodeKind::RegExpLiteral => {
          let pattern = cvt.cvt_label(gc, hermes_get_RegExpLiteral_pattern(n));
          let flags = cvt.cvt_label(gc, hermes_get_RegExpLiteral_flags(n));
          let mut template = ast::template::RegExpLiteral {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  pattern,
                  flags,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::RegExpLiteral::build_template(gc, template)
        }
        NodeKind::BigIntLiteral => {
          let bigint = cvt.cvt_label(gc, hermes_get_BigIntLiteral_bigint(n));
          let mut template = ast::template::BigIntLiteral {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  bigint,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::BigIntLiteral::build_template(gc, template)
        }
        NodeKind::ThisExpression => {
          let mut template = ast::template::ThisExpression {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::ThisExpression::build_template(gc, template)
        }
        NodeKind::Super => {
          let mut template = ast::template::Super {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::Super::build_template(gc, template)
        }
        NodeKind::SequenceExpression => {
          let expressions = cvt_node_list(cvt, gc, hermes_get_SequenceExpression_expressions(n));
          let mut template = ast::template::SequenceExpression {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  expressions,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::SequenceExpression::build_template(gc, template)
        }
        NodeKind::ObjectExpression => {
          let properties = cvt_node_list(cvt, gc, hermes_get_ObjectExpression_properties(n));
          let mut template = ast::template::ObjectExpression {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  properties,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::ObjectExpression::build_template(gc, template)
        }
        NodeKind::ArrayExpression => {
          let elements = cvt_node_list(cvt, gc, hermes_get_ArrayExpression_elements(n));
          let trailing_comma = hermes_get_ArrayExpression_trailingComma(n);
          let mut template = ast::template::ArrayExpression {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  elements,
                  trailing_comma,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::ArrayExpression::build_template(gc, template)
        }
        NodeKind::SpreadElement => {
          let argument = cvt_node_ptr(cvt, gc, hermes_get_SpreadElement_argument(n));
          let mut template = ast::template::SpreadElement {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  argument,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::SpreadElement::build_template(gc, template)
        }
        NodeKind::NewExpression => {
          let callee = cvt_node_ptr(cvt, gc, hermes_get_NewExpression_callee(n));
          let type_arguments = cvt_node_ptr_opt(cvt, gc, hermes_get_NewExpression_typeArguments(n));
          let arguments = cvt_node_list(cvt, gc, hermes_get_NewExpression_arguments(n));
          let mut template = ast::template::NewExpression {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  callee,
                  type_arguments,
                  arguments,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::NewExpression::build_template(gc, template)
        }
        NodeKind::YieldExpression => {
          let argument = cvt_node_ptr_opt(cvt, gc, hermes_get_YieldExpression_argument(n));
          let delegate = hermes_get_YieldExpression_delegate(n);
          let mut template = ast::template::YieldExpression {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  argument,
                  delegate,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::YieldExpression::build_template(gc, template)
        }
        NodeKind::AwaitExpression => {
          let argument = cvt_node_ptr(cvt, gc, hermes_get_AwaitExpression_argument(n));
          let mut template = ast::template::AwaitExpression {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  argument,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::AwaitExpression::build_template(gc, template)
        }
        NodeKind::ImportExpression => {
          let source = cvt_node_ptr(cvt, gc, hermes_get_ImportExpression_source(n));
          let attributes = cvt_node_ptr_opt(cvt, gc, hermes_get_ImportExpression_attributes(n));
          let mut template = ast::template::ImportExpression {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  source,
                  attributes,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::ImportExpression::build_template(gc, template)
        }
        NodeKind::CallExpression => {
          let callee = cvt_node_ptr(cvt, gc, hermes_get_CallExpression_callee(n));
          let type_arguments = cvt_node_ptr_opt(cvt, gc, hermes_get_CallExpression_typeArguments(n));
          let arguments = cvt_node_list(cvt, gc, hermes_get_CallExpression_arguments(n));
          let mut template = ast::template::CallExpression {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  callee,
                  type_arguments,
                  arguments,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::CallExpression::build_template(gc, template)
        }
        NodeKind::OptionalCallExpression => {
          let callee = cvt_node_ptr(cvt, gc, hermes_get_OptionalCallExpression_callee(n));
          let type_arguments = cvt_node_ptr_opt(cvt, gc, hermes_get_OptionalCallExpression_typeArguments(n));
          let arguments = cvt_node_list(cvt, gc, hermes_get_OptionalCallExpression_arguments(n));
          let optional = hermes_get_OptionalCallExpression_optional(n);
          let mut template = ast::template::OptionalCallExpression {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  callee,
                  type_arguments,
                  arguments,
                  optional,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::OptionalCallExpression::build_template(gc, template)
        }
        NodeKind::AssignmentExpression => {
          let operator = cvt_enum(hermes_get_AssignmentExpression_operator(n));
          let left = cvt_node_ptr(cvt, gc, hermes_get_AssignmentExpression_left(n));
          let right = cvt_node_ptr(cvt, gc, hermes_get_AssignmentExpression_right(n));
          let mut template = ast::template::AssignmentExpression {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  operator,
                  left,
                  right,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::AssignmentExpression::build_template(gc, template)
        }
        NodeKind::UnaryExpression => {
          let operator = cvt_enum(hermes_get_UnaryExpression_operator(n));
          let argument = cvt_node_ptr(cvt, gc, hermes_get_UnaryExpression_argument(n));
          let prefix = hermes_get_UnaryExpression_prefix(n);
          let mut template = ast::template::UnaryExpression {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  operator,
                  argument,
                  prefix,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::UnaryExpression::build_template(gc, template)
        }
        NodeKind::UpdateExpression => {
          let operator = cvt_enum(hermes_get_UpdateExpression_operator(n));
          let argument = cvt_node_ptr(cvt, gc, hermes_get_UpdateExpression_argument(n));
          let prefix = hermes_get_UpdateExpression_prefix(n);
          let mut template = ast::template::UpdateExpression {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  operator,
                  argument,
                  prefix,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::UpdateExpression::build_template(gc, template)
        }
        NodeKind::MemberExpression => {
          let object = cvt_node_ptr(cvt, gc, hermes_get_MemberExpression_object(n));
          let property = cvt_node_ptr(cvt, gc, hermes_get_MemberExpression_property(n));
          let computed = hermes_get_MemberExpression_computed(n);
          let mut template = ast::template::MemberExpression {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  object,
                  property,
                  computed,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::MemberExpression::build_template(gc, template)
        }
        NodeKind::OptionalMemberExpression => {
          let object = cvt_node_ptr(cvt, gc, hermes_get_OptionalMemberExpression_object(n));
          let property = cvt_node_ptr(cvt, gc, hermes_get_OptionalMemberExpression_property(n));
          let computed = hermes_get_OptionalMemberExpression_computed(n);
          let optional = hermes_get_OptionalMemberExpression_optional(n);
          let mut template = ast::template::OptionalMemberExpression {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  object,
                  property,
                  computed,
                  optional,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::OptionalMemberExpression::build_template(gc, template)
        }
        NodeKind::LogicalExpression => {
          let left = cvt_node_ptr(cvt, gc, hermes_get_LogicalExpression_left(n));
          let right = cvt_node_ptr(cvt, gc, hermes_get_LogicalExpression_right(n));
          let operator = cvt_enum(hermes_get_LogicalExpression_operator(n));
          let mut template = ast::template::LogicalExpression {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  left,
                  right,
                  operator,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::LogicalExpression::build_template(gc, template)
        }
        NodeKind::ConditionalExpression => {
          let test = cvt_node_ptr(cvt, gc, hermes_get_ConditionalExpression_test(n));
          let alternate = cvt_node_ptr(cvt, gc, hermes_get_ConditionalExpression_alternate(n));
          let consequent = cvt_node_ptr(cvt, gc, hermes_get_ConditionalExpression_consequent(n));
          let mut template = ast::template::ConditionalExpression {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  test,
                  alternate,
                  consequent,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::ConditionalExpression::build_template(gc, template)
        }
        NodeKind::BinaryExpression => {
          let left = cvt_node_ptr(cvt, gc, hermes_get_BinaryExpression_left(n));
          let right = cvt_node_ptr(cvt, gc, hermes_get_BinaryExpression_right(n));
          let operator = cvt_enum(hermes_get_BinaryExpression_operator(n));
          let mut template = ast::template::BinaryExpression {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  left,
                  right,
                  operator,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::BinaryExpression::build_template(gc, template)
        }
        NodeKind::Directive => {
          let value = cvt_node_ptr(cvt, gc, hermes_get_Directive_value(n));
          let mut template = ast::template::Directive {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  value,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::Directive::build_template(gc, template)
        }
        NodeKind::DirectiveLiteral => {
          let value = cvt.cvt_string(gc, hermes_get_DirectiveLiteral_value(n));
          let mut template = ast::template::DirectiveLiteral {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  value,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::DirectiveLiteral::build_template(gc, template)
        }
        NodeKind::Identifier => {
          let name = cvt.cvt_label(gc, hermes_get_Identifier_name(n));
          let type_annotation = cvt_node_ptr_opt(cvt, gc, hermes_get_Identifier_typeAnnotation(n));
          let optional = hermes_get_Identifier_optional(n);
          let mut template = ast::template::Identifier {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  name,
                  type_annotation,
                  optional,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::Identifier::build_template(gc, template)
        }
        NodeKind::PrivateName => {
          let id = cvt_node_ptr(cvt, gc, hermes_get_PrivateName_id(n));
          let mut template = ast::template::PrivateName {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  id,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::PrivateName::build_template(gc, template)
        }
        NodeKind::MetaProperty => {
          let meta = cvt_node_ptr(cvt, gc, hermes_get_MetaProperty_meta(n));
          let property = cvt_node_ptr(cvt, gc, hermes_get_MetaProperty_property(n));
          let mut template = ast::template::MetaProperty {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  meta,
                  property,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::MetaProperty::build_template(gc, template)
        }
        NodeKind::SwitchCase => {
          let test = cvt_node_ptr_opt(cvt, gc, hermes_get_SwitchCase_test(n));
          let consequent = cvt_node_list(cvt, gc, hermes_get_SwitchCase_consequent(n));
          let mut template = ast::template::SwitchCase {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  test,
                  consequent,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::SwitchCase::build_template(gc, template)
        }
        NodeKind::CatchClause => {
          let param = cvt_node_ptr_opt(cvt, gc, hermes_get_CatchClause_param(n));
          let body = cvt_node_ptr(cvt, gc, hermes_get_CatchClause_body(n));
          let mut template = ast::template::CatchClause {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  param,
                  body,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::CatchClause::build_template(gc, template)
        }
        NodeKind::VariableDeclarator => {
          let init = cvt_node_ptr_opt(cvt, gc, hermes_get_VariableDeclarator_init(n));
          let id = cvt_node_ptr(cvt, gc, hermes_get_VariableDeclarator_id(n));
          let mut template = ast::template::VariableDeclarator {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  init,
                  id,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::VariableDeclarator::build_template(gc, template)
        }
        NodeKind::VariableDeclaration => {
          let kind = cvt_enum(hermes_get_VariableDeclaration_kind(n));
          let declarations = cvt_node_list(cvt, gc, hermes_get_VariableDeclaration_declarations(n));
          let mut template = ast::template::VariableDeclaration {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  kind,
                  declarations,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::VariableDeclaration::build_template(gc, template)
        }
        NodeKind::TemplateLiteral => {
          let quasis = cvt_node_list(cvt, gc, hermes_get_TemplateLiteral_quasis(n));
          let expressions = cvt_node_list(cvt, gc, hermes_get_TemplateLiteral_expressions(n));
          let mut template = ast::template::TemplateLiteral {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  quasis,
                  expressions,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::TemplateLiteral::build_template(gc, template)
        }
        NodeKind::TaggedTemplateExpression => {
          let tag = cvt_node_ptr(cvt, gc, hermes_get_TaggedTemplateExpression_tag(n));
          let quasi = cvt_node_ptr(cvt, gc, hermes_get_TaggedTemplateExpression_quasi(n));
          let mut template = ast::template::TaggedTemplateExpression {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  tag,
                  quasi,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::TaggedTemplateExpression::build_template(gc, template)
        }
        NodeKind::TemplateElement => {
          let tail = hermes_get_TemplateElement_tail(n);
          let cooked = cvt.cvt_string_opt(gc, hermes_get_TemplateElement_cooked(n));
          let raw = cvt.cvt_label(gc, hermes_get_TemplateElement_raw(n));
          let mut template = ast::template::TemplateElement {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  tail,
                  cooked,
                  raw,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::TemplateElement::build_template(gc, template)
        }
        NodeKind::Property => {
          let key = cvt_node_ptr(cvt, gc, hermes_get_Property_key(n));
          let value = cvt_node_ptr(cvt, gc, hermes_get_Property_value(n));
          let kind = cvt_enum(hermes_get_Property_kind(n));
          let computed = hermes_get_Property_computed(n);
          let method = hermes_get_Property_method(n);
          let shorthand = hermes_get_Property_shorthand(n);
          let mut template = ast::template::Property {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  key,
                  value,
                  kind,
                  computed,
                  method,
                  shorthand,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::Property::build_template(gc, template)
        }
        NodeKind::ClassDeclaration => {
          let id = cvt_node_ptr_opt(cvt, gc, hermes_get_ClassDeclaration_id(n));
          let type_parameters = cvt_node_ptr_opt(cvt, gc, hermes_get_ClassDeclaration_typeParameters(n));
          let super_class = cvt_node_ptr_opt(cvt, gc, hermes_get_ClassDeclaration_superClass(n));
          let super_type_parameters = cvt_node_ptr_opt(cvt, gc, hermes_get_ClassDeclaration_superTypeParameters(n));
          let implements = cvt_node_list(cvt, gc, hermes_get_ClassDeclaration_implements(n));
          let decorators = cvt_node_list(cvt, gc, hermes_get_ClassDeclaration_decorators(n));
          let body = cvt_node_ptr(cvt, gc, hermes_get_ClassDeclaration_body(n));
          let mut template = ast::template::ClassDeclaration {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  id,
                  type_parameters,
                  super_class,
                  super_type_parameters,
                  implements,
                  decorators,
                  body,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::ClassDeclaration::build_template(gc, template)
        }
        NodeKind::ClassExpression => {
          let id = cvt_node_ptr_opt(cvt, gc, hermes_get_ClassExpression_id(n));
          let type_parameters = cvt_node_ptr_opt(cvt, gc, hermes_get_ClassExpression_typeParameters(n));
          let super_class = cvt_node_ptr_opt(cvt, gc, hermes_get_ClassExpression_superClass(n));
          let super_type_parameters = cvt_node_ptr_opt(cvt, gc, hermes_get_ClassExpression_superTypeParameters(n));
          let implements = cvt_node_list(cvt, gc, hermes_get_ClassExpression_implements(n));
          let decorators = cvt_node_list(cvt, gc, hermes_get_ClassExpression_decorators(n));
          let body = cvt_node_ptr(cvt, gc, hermes_get_ClassExpression_body(n));
          let mut template = ast::template::ClassExpression {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  id,
                  type_parameters,
                  super_class,
                  super_type_parameters,
                  implements,
                  decorators,
                  body,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::ClassExpression::build_template(gc, template)
        }
        NodeKind::ClassBody => {
          let body = cvt_node_list(cvt, gc, hermes_get_ClassBody_body(n));
          let mut template = ast::template::ClassBody {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  body,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::ClassBody::build_template(gc, template)
        }
        NodeKind::ClassProperty => {
          let key = cvt_node_ptr(cvt, gc, hermes_get_ClassProperty_key(n));
          let value = cvt_node_ptr_opt(cvt, gc, hermes_get_ClassProperty_value(n));
          let computed = hermes_get_ClassProperty_computed(n);
          let is_static = hermes_get_ClassProperty_static(n);
          let declare = hermes_get_ClassProperty_declare(n);
          let optional = hermes_get_ClassProperty_optional(n);
          let variance = cvt_node_ptr_opt(cvt, gc, hermes_get_ClassProperty_variance(n));
          let type_annotation = cvt_node_ptr_opt(cvt, gc, hermes_get_ClassProperty_typeAnnotation(n));
          let ts_modifiers = cvt_node_ptr_opt(cvt, gc, hermes_get_ClassProperty_tsModifiers(n));
          let mut template = ast::template::ClassProperty {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  key,
                  value,
                  computed,
                  is_static,
                  declare,
                  optional,
                  variance,
                  type_annotation,
                  ts_modifiers,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::ClassProperty::build_template(gc, template)
        }
        NodeKind::ClassPrivateProperty => {
          let key = cvt_node_ptr(cvt, gc, hermes_get_ClassPrivateProperty_key(n));
          let value = cvt_node_ptr_opt(cvt, gc, hermes_get_ClassPrivateProperty_value(n));
          let is_static = hermes_get_ClassPrivateProperty_static(n);
          let declare = hermes_get_ClassPrivateProperty_declare(n);
          let optional = hermes_get_ClassPrivateProperty_optional(n);
          let variance = cvt_node_ptr_opt(cvt, gc, hermes_get_ClassPrivateProperty_variance(n));
          let type_annotation = cvt_node_ptr_opt(cvt, gc, hermes_get_ClassPrivateProperty_typeAnnotation(n));
          let ts_modifiers = cvt_node_ptr_opt(cvt, gc, hermes_get_ClassPrivateProperty_tsModifiers(n));
          let mut template = ast::template::ClassPrivateProperty {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  key,
                  value,
                  is_static,
                  declare,
                  optional,
                  variance,
                  type_annotation,
                  ts_modifiers,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::ClassPrivateProperty::build_template(gc, template)
        }
        NodeKind::MethodDefinition => {
          let key = cvt_node_ptr(cvt, gc, hermes_get_MethodDefinition_key(n));
          let value = cvt_node_ptr(cvt, gc, hermes_get_MethodDefinition_value(n));
          let kind = cvt_enum(hermes_get_MethodDefinition_kind(n));
          let computed = hermes_get_MethodDefinition_computed(n);
          let is_static = hermes_get_MethodDefinition_static(n);
          let mut template = ast::template::MethodDefinition {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  key,
                  value,
                  kind,
                  computed,
                  is_static,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::MethodDefinition::build_template(gc, template)
        }
        NodeKind::ImportDeclaration => {
          let specifiers = cvt_node_list(cvt, gc, hermes_get_ImportDeclaration_specifiers(n));
          let source = cvt_node_ptr(cvt, gc, hermes_get_ImportDeclaration_source(n));
          let assertions = cvt_node_list_opt(cvt, gc, hermes_get_ImportDeclaration_assertions(n));
          let import_kind = cvt_enum(hermes_get_ImportDeclaration_importKind(n));
          let mut template = ast::template::ImportDeclaration {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  specifiers,
                  source,
                  assertions,
                  import_kind,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::ImportDeclaration::build_template(gc, template)
        }
        NodeKind::ImportSpecifier => {
          let imported = cvt_node_ptr(cvt, gc, hermes_get_ImportSpecifier_imported(n));
          let local = cvt_node_ptr(cvt, gc, hermes_get_ImportSpecifier_local(n));
          let import_kind = cvt_enum(hermes_get_ImportSpecifier_importKind(n));
          let mut template = ast::template::ImportSpecifier {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  imported,
                  local,
                  import_kind,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::ImportSpecifier::build_template(gc, template)
        }
        NodeKind::ImportDefaultSpecifier => {
          let local = cvt_node_ptr(cvt, gc, hermes_get_ImportDefaultSpecifier_local(n));
          let mut template = ast::template::ImportDefaultSpecifier {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  local,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::ImportDefaultSpecifier::build_template(gc, template)
        }
        NodeKind::ImportNamespaceSpecifier => {
          let local = cvt_node_ptr(cvt, gc, hermes_get_ImportNamespaceSpecifier_local(n));
          let mut template = ast::template::ImportNamespaceSpecifier {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  local,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::ImportNamespaceSpecifier::build_template(gc, template)
        }
        NodeKind::ImportAttribute => {
          let key = cvt_node_ptr(cvt, gc, hermes_get_ImportAttribute_key(n));
          let value = cvt_node_ptr(cvt, gc, hermes_get_ImportAttribute_value(n));
          let mut template = ast::template::ImportAttribute {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  key,
                  value,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::ImportAttribute::build_template(gc, template)
        }
        NodeKind::ExportNamedDeclaration => {
          let declaration = cvt_node_ptr_opt(cvt, gc, hermes_get_ExportNamedDeclaration_declaration(n));
          let specifiers = cvt_node_list(cvt, gc, hermes_get_ExportNamedDeclaration_specifiers(n));
          let source = cvt_node_ptr_opt(cvt, gc, hermes_get_ExportNamedDeclaration_source(n));
          let export_kind = cvt_enum(hermes_get_ExportNamedDeclaration_exportKind(n));
          let mut template = ast::template::ExportNamedDeclaration {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  declaration,
                  specifiers,
                  source,
                  export_kind,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::ExportNamedDeclaration::build_template(gc, template)
        }
        NodeKind::ExportSpecifier => {
          let exported = cvt_node_ptr(cvt, gc, hermes_get_ExportSpecifier_exported(n));
          let local = cvt_node_ptr(cvt, gc, hermes_get_ExportSpecifier_local(n));
          let mut template = ast::template::ExportSpecifier {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  exported,
                  local,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::ExportSpecifier::build_template(gc, template)
        }
        NodeKind::ExportNamespaceSpecifier => {
          let exported = cvt_node_ptr(cvt, gc, hermes_get_ExportNamespaceSpecifier_exported(n));
          let mut template = ast::template::ExportNamespaceSpecifier {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  exported,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::ExportNamespaceSpecifier::build_template(gc, template)
        }
        NodeKind::ExportDefaultDeclaration => {
          let declaration = cvt_node_ptr(cvt, gc, hermes_get_ExportDefaultDeclaration_declaration(n));
          let mut template = ast::template::ExportDefaultDeclaration {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  declaration,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::ExportDefaultDeclaration::build_template(gc, template)
        }
        NodeKind::ExportAllDeclaration => {
          let source = cvt_node_ptr(cvt, gc, hermes_get_ExportAllDeclaration_source(n));
          let export_kind = cvt_enum(hermes_get_ExportAllDeclaration_exportKind(n));
          let mut template = ast::template::ExportAllDeclaration {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  source,
                  export_kind,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::ExportAllDeclaration::build_template(gc, template)
        }
        NodeKind::ObjectPattern => {
          let properties = cvt_node_list(cvt, gc, hermes_get_ObjectPattern_properties(n));
          let type_annotation = cvt_node_ptr_opt(cvt, gc, hermes_get_ObjectPattern_typeAnnotation(n));
          let mut template = ast::template::ObjectPattern {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  properties,
                  type_annotation,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::ObjectPattern::build_template(gc, template)
        }
        NodeKind::ArrayPattern => {
          let elements = cvt_node_list(cvt, gc, hermes_get_ArrayPattern_elements(n));
          let type_annotation = cvt_node_ptr_opt(cvt, gc, hermes_get_ArrayPattern_typeAnnotation(n));
          let mut template = ast::template::ArrayPattern {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  elements,
                  type_annotation,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::ArrayPattern::build_template(gc, template)
        }
        NodeKind::RestElement => {
          let argument = cvt_node_ptr(cvt, gc, hermes_get_RestElement_argument(n));
          let mut template = ast::template::RestElement {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  argument,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::RestElement::build_template(gc, template)
        }
        NodeKind::AssignmentPattern => {
          let left = cvt_node_ptr(cvt, gc, hermes_get_AssignmentPattern_left(n));
          let right = cvt_node_ptr(cvt, gc, hermes_get_AssignmentPattern_right(n));
          let mut template = ast::template::AssignmentPattern {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  left,
                  right,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::AssignmentPattern::build_template(gc, template)
        }
        NodeKind::JSXIdentifier => {
          let name = cvt.cvt_label(gc, hermes_get_JSXIdentifier_name(n));
          let mut template = ast::template::JSXIdentifier {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  name,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::JSXIdentifier::build_template(gc, template)
        }
        NodeKind::JSXMemberExpression => {
          let object = cvt_node_ptr(cvt, gc, hermes_get_JSXMemberExpression_object(n));
          let property = cvt_node_ptr(cvt, gc, hermes_get_JSXMemberExpression_property(n));
          let mut template = ast::template::JSXMemberExpression {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  object,
                  property,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::JSXMemberExpression::build_template(gc, template)
        }
        NodeKind::JSXNamespacedName => {
          let namespace = cvt_node_ptr(cvt, gc, hermes_get_JSXNamespacedName_namespace(n));
          let name = cvt_node_ptr(cvt, gc, hermes_get_JSXNamespacedName_name(n));
          let mut template = ast::template::JSXNamespacedName {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  namespace,
                  name,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::JSXNamespacedName::build_template(gc, template)
        }
        NodeKind::JSXEmptyExpression => {
          let mut template = ast::template::JSXEmptyExpression {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::JSXEmptyExpression::build_template(gc, template)
        }
        NodeKind::JSXExpressionContainer => {
          let expression = cvt_node_ptr(cvt, gc, hermes_get_JSXExpressionContainer_expression(n));
          let mut template = ast::template::JSXExpressionContainer {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  expression,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::JSXExpressionContainer::build_template(gc, template)
        }
        NodeKind::JSXSpreadChild => {
          let expression = cvt_node_ptr(cvt, gc, hermes_get_JSXSpreadChild_expression(n));
          let mut template = ast::template::JSXSpreadChild {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  expression,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::JSXSpreadChild::build_template(gc, template)
        }
        NodeKind::JSXOpeningElement => {
          let name = cvt_node_ptr(cvt, gc, hermes_get_JSXOpeningElement_name(n));
          let attributes = cvt_node_list(cvt, gc, hermes_get_JSXOpeningElement_attributes(n));
          let self_closing = hermes_get_JSXOpeningElement_selfClosing(n);
          let type_arguments = cvt_node_ptr_opt(cvt, gc, hermes_get_JSXOpeningElement_typeArguments(n));
          let mut template = ast::template::JSXOpeningElement {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  name,
                  attributes,
                  self_closing,
                  type_arguments,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::JSXOpeningElement::build_template(gc, template)
        }
        NodeKind::JSXClosingElement => {
          let name = cvt_node_ptr(cvt, gc, hermes_get_JSXClosingElement_name(n));
          let mut template = ast::template::JSXClosingElement {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  name,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::JSXClosingElement::build_template(gc, template)
        }
        NodeKind::JSXAttribute => {
          let name = cvt_node_ptr(cvt, gc, hermes_get_JSXAttribute_name(n));
          let value = cvt_node_ptr_opt(cvt, gc, hermes_get_JSXAttribute_value(n));
          let mut template = ast::template::JSXAttribute {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  name,
                  value,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::JSXAttribute::build_template(gc, template)
        }
        NodeKind::JSXSpreadAttribute => {
          let argument = cvt_node_ptr(cvt, gc, hermes_get_JSXSpreadAttribute_argument(n));
          let mut template = ast::template::JSXSpreadAttribute {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  argument,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::JSXSpreadAttribute::build_template(gc, template)
        }
        NodeKind::JSXStringLiteral => {
          let value = cvt.cvt_string(gc, hermes_get_JSXStringLiteral_value(n));
          let raw = cvt.cvt_label(gc, hermes_get_JSXStringLiteral_raw(n));
          let mut template = ast::template::JSXStringLiteral {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  value,
                  raw,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::JSXStringLiteral::build_template(gc, template)
        }
        NodeKind::JSXText => {
          let value = cvt.cvt_string(gc, hermes_get_JSXText_value(n));
          let raw = cvt.cvt_label(gc, hermes_get_JSXText_raw(n));
          let mut template = ast::template::JSXText {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  value,
                  raw,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::JSXText::build_template(gc, template)
        }
        NodeKind::JSXElement => {
          let opening_element = cvt_node_ptr(cvt, gc, hermes_get_JSXElement_openingElement(n));
          let children = cvt_node_list(cvt, gc, hermes_get_JSXElement_children(n));
          let closing_element = cvt_node_ptr_opt(cvt, gc, hermes_get_JSXElement_closingElement(n));
          let mut template = ast::template::JSXElement {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  opening_element,
                  children,
                  closing_element,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::JSXElement::build_template(gc, template)
        }
        NodeKind::JSXFragment => {
          let opening_fragment = cvt_node_ptr(cvt, gc, hermes_get_JSXFragment_openingFragment(n));
          let children = cvt_node_list(cvt, gc, hermes_get_JSXFragment_children(n));
          let closing_fragment = cvt_node_ptr(cvt, gc, hermes_get_JSXFragment_closingFragment(n));
          let mut template = ast::template::JSXFragment {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  opening_fragment,
                  children,
                  closing_fragment,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::JSXFragment::build_template(gc, template)
        }
        NodeKind::JSXOpeningFragment => {
          let mut template = ast::template::JSXOpeningFragment {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::JSXOpeningFragment::build_template(gc, template)
        }
        NodeKind::JSXClosingFragment => {
          let mut template = ast::template::JSXClosingFragment {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::JSXClosingFragment::build_template(gc, template)
        }
        NodeKind::ExistsTypeAnnotation => {
          let mut template = ast::template::ExistsTypeAnnotation {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::ExistsTypeAnnotation::build_template(gc, template)
        }
        NodeKind::EmptyTypeAnnotation => {
          let mut template = ast::template::EmptyTypeAnnotation {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::EmptyTypeAnnotation::build_template(gc, template)
        }
        NodeKind::StringTypeAnnotation => {
          let mut template = ast::template::StringTypeAnnotation {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::StringTypeAnnotation::build_template(gc, template)
        }
        NodeKind::NumberTypeAnnotation => {
          let mut template = ast::template::NumberTypeAnnotation {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::NumberTypeAnnotation::build_template(gc, template)
        }
        NodeKind::StringLiteralTypeAnnotation => {
          let value = cvt.cvt_string(gc, hermes_get_StringLiteralTypeAnnotation_value(n));
          let raw = cvt.cvt_string(gc, hermes_get_StringLiteralTypeAnnotation_raw(n));
          let mut template = ast::template::StringLiteralTypeAnnotation {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  value,
                  raw,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::StringLiteralTypeAnnotation::build_template(gc, template)
        }
        NodeKind::NumberLiteralTypeAnnotation => {
          let value = hermes_get_NumberLiteralTypeAnnotation_value(n);
          let raw = cvt.cvt_label(gc, hermes_get_NumberLiteralTypeAnnotation_raw(n));
          let mut template = ast::template::NumberLiteralTypeAnnotation {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  value,
                  raw,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::NumberLiteralTypeAnnotation::build_template(gc, template)
        }
        NodeKind::BigIntLiteralTypeAnnotation => {
          let raw = cvt.cvt_label(gc, hermes_get_BigIntLiteralTypeAnnotation_raw(n));
          let mut template = ast::template::BigIntLiteralTypeAnnotation {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  raw,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::BigIntLiteralTypeAnnotation::build_template(gc, template)
        }
        NodeKind::BooleanTypeAnnotation => {
          let mut template = ast::template::BooleanTypeAnnotation {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::BooleanTypeAnnotation::build_template(gc, template)
        }
        NodeKind::BooleanLiteralTypeAnnotation => {
          let value = hermes_get_BooleanLiteralTypeAnnotation_value(n);
          let raw = cvt.cvt_label(gc, hermes_get_BooleanLiteralTypeAnnotation_raw(n));
          let mut template = ast::template::BooleanLiteralTypeAnnotation {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  value,
                  raw,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::BooleanLiteralTypeAnnotation::build_template(gc, template)
        }
        NodeKind::NullLiteralTypeAnnotation => {
          let mut template = ast::template::NullLiteralTypeAnnotation {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::NullLiteralTypeAnnotation::build_template(gc, template)
        }
        NodeKind::SymbolTypeAnnotation => {
          let mut template = ast::template::SymbolTypeAnnotation {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::SymbolTypeAnnotation::build_template(gc, template)
        }
        NodeKind::AnyTypeAnnotation => {
          let mut template = ast::template::AnyTypeAnnotation {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::AnyTypeAnnotation::build_template(gc, template)
        }
        NodeKind::MixedTypeAnnotation => {
          let mut template = ast::template::MixedTypeAnnotation {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::MixedTypeAnnotation::build_template(gc, template)
        }
        NodeKind::BigIntTypeAnnotation => {
          let mut template = ast::template::BigIntTypeAnnotation {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::BigIntTypeAnnotation::build_template(gc, template)
        }
        NodeKind::VoidTypeAnnotation => {
          let mut template = ast::template::VoidTypeAnnotation {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::VoidTypeAnnotation::build_template(gc, template)
        }
        NodeKind::FunctionTypeAnnotation => {
          let params = cvt_node_list(cvt, gc, hermes_get_FunctionTypeAnnotation_params(n));
          let this = cvt_node_ptr_opt(cvt, gc, hermes_get_FunctionTypeAnnotation_this(n));
          let return_type = cvt_node_ptr(cvt, gc, hermes_get_FunctionTypeAnnotation_returnType(n));
          let rest = cvt_node_ptr_opt(cvt, gc, hermes_get_FunctionTypeAnnotation_rest(n));
          let type_parameters = cvt_node_ptr_opt(cvt, gc, hermes_get_FunctionTypeAnnotation_typeParameters(n));
          let mut template = ast::template::FunctionTypeAnnotation {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  params,
                  this,
                  return_type,
                  rest,
                  type_parameters,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::FunctionTypeAnnotation::build_template(gc, template)
        }
        NodeKind::FunctionTypeParam => {
          let name = cvt_node_ptr_opt(cvt, gc, hermes_get_FunctionTypeParam_name(n));
          let type_annotation = cvt_node_ptr(cvt, gc, hermes_get_FunctionTypeParam_typeAnnotation(n));
          let optional = hermes_get_FunctionTypeParam_optional(n);
          let mut template = ast::template::FunctionTypeParam {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  name,
                  type_annotation,
                  optional,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::FunctionTypeParam::build_template(gc, template)
        }
        NodeKind::ComponentTypeAnnotation => {
          let params = cvt_node_list(cvt, gc, hermes_get_ComponentTypeAnnotation_params(n));
          let rest = cvt_node_ptr_opt(cvt, gc, hermes_get_ComponentTypeAnnotation_rest(n));
          let type_parameters = cvt_node_ptr_opt(cvt, gc, hermes_get_ComponentTypeAnnotation_typeParameters(n));
          let renders_type = cvt_node_ptr_opt(cvt, gc, hermes_get_ComponentTypeAnnotation_rendersType(n));
          let mut template = ast::template::ComponentTypeAnnotation {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  params,
                  rest,
                  type_parameters,
                  renders_type,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::ComponentTypeAnnotation::build_template(gc, template)
        }
        NodeKind::ComponentTypeParameter => {
          let name = cvt_node_ptr_opt(cvt, gc, hermes_get_ComponentTypeParameter_name(n));
          let type_annotation = cvt_node_ptr(cvt, gc, hermes_get_ComponentTypeParameter_typeAnnotation(n));
          let optional = hermes_get_ComponentTypeParameter_optional(n);
          let mut template = ast::template::ComponentTypeParameter {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  name,
                  type_annotation,
                  optional,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::ComponentTypeParameter::build_template(gc, template)
        }
        NodeKind::NullableTypeAnnotation => {
          let type_annotation = cvt_node_ptr(cvt, gc, hermes_get_NullableTypeAnnotation_typeAnnotation(n));
          let mut template = ast::template::NullableTypeAnnotation {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  type_annotation,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::NullableTypeAnnotation::build_template(gc, template)
        }
        NodeKind::QualifiedTypeIdentifier => {
          let qualification = cvt_node_ptr(cvt, gc, hermes_get_QualifiedTypeIdentifier_qualification(n));
          let id = cvt_node_ptr(cvt, gc, hermes_get_QualifiedTypeIdentifier_id(n));
          let mut template = ast::template::QualifiedTypeIdentifier {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  qualification,
                  id,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::QualifiedTypeIdentifier::build_template(gc, template)
        }
        NodeKind::TypeofTypeAnnotation => {
          let argument = cvt_node_ptr(cvt, gc, hermes_get_TypeofTypeAnnotation_argument(n));
          let mut template = ast::template::TypeofTypeAnnotation {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  argument,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::TypeofTypeAnnotation::build_template(gc, template)
        }
        NodeKind::KeyofTypeAnnotation => {
          let argument = cvt_node_ptr(cvt, gc, hermes_get_KeyofTypeAnnotation_argument(n));
          let mut template = ast::template::KeyofTypeAnnotation {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  argument,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::KeyofTypeAnnotation::build_template(gc, template)
        }
        NodeKind::QualifiedTypeofIdentifier => {
          let qualification = cvt_node_ptr(cvt, gc, hermes_get_QualifiedTypeofIdentifier_qualification(n));
          let id = cvt_node_ptr(cvt, gc, hermes_get_QualifiedTypeofIdentifier_id(n));
          let mut template = ast::template::QualifiedTypeofIdentifier {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  qualification,
                  id,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::QualifiedTypeofIdentifier::build_template(gc, template)
        }
        NodeKind::TupleTypeAnnotation => {
          let types = cvt_node_list(cvt, gc, hermes_get_TupleTypeAnnotation_types(n));
          let mut template = ast::template::TupleTypeAnnotation {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  types,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::TupleTypeAnnotation::build_template(gc, template)
        }
        NodeKind::TupleTypeSpreadElement => {
          let label = cvt_node_ptr_opt(cvt, gc, hermes_get_TupleTypeSpreadElement_label(n));
          let type_annotation = cvt_node_ptr(cvt, gc, hermes_get_TupleTypeSpreadElement_typeAnnotation(n));
          let mut template = ast::template::TupleTypeSpreadElement {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  label,
                  type_annotation,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::TupleTypeSpreadElement::build_template(gc, template)
        }
        NodeKind::TupleTypeLabeledElement => {
          let label = cvt_node_ptr(cvt, gc, hermes_get_TupleTypeLabeledElement_label(n));
          let element_type = cvt_node_ptr(cvt, gc, hermes_get_TupleTypeLabeledElement_elementType(n));
          let optional = hermes_get_TupleTypeLabeledElement_optional(n);
          let variance = cvt_node_ptr_opt(cvt, gc, hermes_get_TupleTypeLabeledElement_variance(n));
          let mut template = ast::template::TupleTypeLabeledElement {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  label,
                  element_type,
                  optional,
                  variance,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::TupleTypeLabeledElement::build_template(gc, template)
        }
        NodeKind::ArrayTypeAnnotation => {
          let element_type = cvt_node_ptr(cvt, gc, hermes_get_ArrayTypeAnnotation_elementType(n));
          let mut template = ast::template::ArrayTypeAnnotation {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  element_type,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::ArrayTypeAnnotation::build_template(gc, template)
        }
        NodeKind::InferTypeAnnotation => {
          let type_parameter = cvt_node_ptr(cvt, gc, hermes_get_InferTypeAnnotation_typeParameter(n));
          let mut template = ast::template::InferTypeAnnotation {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  type_parameter,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::InferTypeAnnotation::build_template(gc, template)
        }
        NodeKind::UnionTypeAnnotation => {
          let types = cvt_node_list(cvt, gc, hermes_get_UnionTypeAnnotation_types(n));
          let mut template = ast::template::UnionTypeAnnotation {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  types,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::UnionTypeAnnotation::build_template(gc, template)
        }
        NodeKind::IntersectionTypeAnnotation => {
          let types = cvt_node_list(cvt, gc, hermes_get_IntersectionTypeAnnotation_types(n));
          let mut template = ast::template::IntersectionTypeAnnotation {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  types,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::IntersectionTypeAnnotation::build_template(gc, template)
        }
        NodeKind::GenericTypeAnnotation => {
          let id = cvt_node_ptr(cvt, gc, hermes_get_GenericTypeAnnotation_id(n));
          let type_parameters = cvt_node_ptr_opt(cvt, gc, hermes_get_GenericTypeAnnotation_typeParameters(n));
          let mut template = ast::template::GenericTypeAnnotation {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  id,
                  type_parameters,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::GenericTypeAnnotation::build_template(gc, template)
        }
        NodeKind::IndexedAccessType => {
          let object_type = cvt_node_ptr(cvt, gc, hermes_get_IndexedAccessType_objectType(n));
          let index_type = cvt_node_ptr(cvt, gc, hermes_get_IndexedAccessType_indexType(n));
          let mut template = ast::template::IndexedAccessType {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  object_type,
                  index_type,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::IndexedAccessType::build_template(gc, template)
        }
        NodeKind::OptionalIndexedAccessType => {
          let object_type = cvt_node_ptr(cvt, gc, hermes_get_OptionalIndexedAccessType_objectType(n));
          let index_type = cvt_node_ptr(cvt, gc, hermes_get_OptionalIndexedAccessType_indexType(n));
          let optional = hermes_get_OptionalIndexedAccessType_optional(n);
          let mut template = ast::template::OptionalIndexedAccessType {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  object_type,
                  index_type,
                  optional,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::OptionalIndexedAccessType::build_template(gc, template)
        }
        NodeKind::ConditionalTypeAnnotation => {
          let check_type = cvt_node_ptr(cvt, gc, hermes_get_ConditionalTypeAnnotation_checkType(n));
          let extends_type = cvt_node_ptr(cvt, gc, hermes_get_ConditionalTypeAnnotation_extendsType(n));
          let true_type = cvt_node_ptr(cvt, gc, hermes_get_ConditionalTypeAnnotation_trueType(n));
          let false_type = cvt_node_ptr(cvt, gc, hermes_get_ConditionalTypeAnnotation_falseType(n));
          let mut template = ast::template::ConditionalTypeAnnotation {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  check_type,
                  extends_type,
                  true_type,
                  false_type,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::ConditionalTypeAnnotation::build_template(gc, template)
        }
        NodeKind::TypePredicate => {
          let parameter_name = cvt_node_ptr(cvt, gc, hermes_get_TypePredicate_parameterName(n));
          let type_annotation = cvt_node_ptr_opt(cvt, gc, hermes_get_TypePredicate_typeAnnotation(n));
          let asserts = hermes_get_TypePredicate_asserts(n);
          let mut template = ast::template::TypePredicate {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  parameter_name,
                  type_annotation,
                  asserts,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::TypePredicate::build_template(gc, template)
        }
        NodeKind::InterfaceTypeAnnotation => {
          let extends = cvt_node_list(cvt, gc, hermes_get_InterfaceTypeAnnotation_extends(n));
          let body = cvt_node_ptr_opt(cvt, gc, hermes_get_InterfaceTypeAnnotation_body(n));
          let mut template = ast::template::InterfaceTypeAnnotation {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  extends,
                  body,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::InterfaceTypeAnnotation::build_template(gc, template)
        }
        NodeKind::TypeAlias => {
          let id = cvt_node_ptr(cvt, gc, hermes_get_TypeAlias_id(n));
          let type_parameters = cvt_node_ptr_opt(cvt, gc, hermes_get_TypeAlias_typeParameters(n));
          let right = cvt_node_ptr(cvt, gc, hermes_get_TypeAlias_right(n));
          let mut template = ast::template::TypeAlias {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  id,
                  type_parameters,
                  right,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::TypeAlias::build_template(gc, template)
        }
        NodeKind::OpaqueType => {
          let id = cvt_node_ptr(cvt, gc, hermes_get_OpaqueType_id(n));
          let type_parameters = cvt_node_ptr_opt(cvt, gc, hermes_get_OpaqueType_typeParameters(n));
          let impltype = cvt_node_ptr(cvt, gc, hermes_get_OpaqueType_impltype(n));
          let supertype = cvt_node_ptr_opt(cvt, gc, hermes_get_OpaqueType_supertype(n));
          let mut template = ast::template::OpaqueType {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  id,
                  type_parameters,
                  impltype,
                  supertype,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::OpaqueType::build_template(gc, template)
        }
        NodeKind::InterfaceDeclaration => {
          let id = cvt_node_ptr(cvt, gc, hermes_get_InterfaceDeclaration_id(n));
          let type_parameters = cvt_node_ptr_opt(cvt, gc, hermes_get_InterfaceDeclaration_typeParameters(n));
          let extends = cvt_node_list(cvt, gc, hermes_get_InterfaceDeclaration_extends(n));
          let body = cvt_node_ptr(cvt, gc, hermes_get_InterfaceDeclaration_body(n));
          let mut template = ast::template::InterfaceDeclaration {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  id,
                  type_parameters,
                  extends,
                  body,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::InterfaceDeclaration::build_template(gc, template)
        }
        NodeKind::DeclareTypeAlias => {
          let id = cvt_node_ptr(cvt, gc, hermes_get_DeclareTypeAlias_id(n));
          let type_parameters = cvt_node_ptr_opt(cvt, gc, hermes_get_DeclareTypeAlias_typeParameters(n));
          let right = cvt_node_ptr(cvt, gc, hermes_get_DeclareTypeAlias_right(n));
          let mut template = ast::template::DeclareTypeAlias {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  id,
                  type_parameters,
                  right,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::DeclareTypeAlias::build_template(gc, template)
        }
        NodeKind::DeclareOpaqueType => {
          let id = cvt_node_ptr(cvt, gc, hermes_get_DeclareOpaqueType_id(n));
          let type_parameters = cvt_node_ptr_opt(cvt, gc, hermes_get_DeclareOpaqueType_typeParameters(n));
          let impltype = cvt_node_ptr_opt(cvt, gc, hermes_get_DeclareOpaqueType_impltype(n));
          let supertype = cvt_node_ptr_opt(cvt, gc, hermes_get_DeclareOpaqueType_supertype(n));
          let mut template = ast::template::DeclareOpaqueType {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  id,
                  type_parameters,
                  impltype,
                  supertype,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::DeclareOpaqueType::build_template(gc, template)
        }
        NodeKind::DeclareInterface => {
          let id = cvt_node_ptr(cvt, gc, hermes_get_DeclareInterface_id(n));
          let type_parameters = cvt_node_ptr_opt(cvt, gc, hermes_get_DeclareInterface_typeParameters(n));
          let extends = cvt_node_list(cvt, gc, hermes_get_DeclareInterface_extends(n));
          let body = cvt_node_ptr(cvt, gc, hermes_get_DeclareInterface_body(n));
          let mut template = ast::template::DeclareInterface {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  id,
                  type_parameters,
                  extends,
                  body,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::DeclareInterface::build_template(gc, template)
        }
        NodeKind::DeclareClass => {
          let id = cvt_node_ptr(cvt, gc, hermes_get_DeclareClass_id(n));
          let type_parameters = cvt_node_ptr_opt(cvt, gc, hermes_get_DeclareClass_typeParameters(n));
          let extends = cvt_node_list(cvt, gc, hermes_get_DeclareClass_extends(n));
          let implements = cvt_node_list(cvt, gc, hermes_get_DeclareClass_implements(n));
          let mixins = cvt_node_list(cvt, gc, hermes_get_DeclareClass_mixins(n));
          let body = cvt_node_ptr(cvt, gc, hermes_get_DeclareClass_body(n));
          let mut template = ast::template::DeclareClass {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  id,
                  type_parameters,
                  extends,
                  implements,
                  mixins,
                  body,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::DeclareClass::build_template(gc, template)
        }
        NodeKind::DeclareFunction => {
          let id = cvt_node_ptr(cvt, gc, hermes_get_DeclareFunction_id(n));
          let predicate = cvt_node_ptr_opt(cvt, gc, hermes_get_DeclareFunction_predicate(n));
          let mut template = ast::template::DeclareFunction {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  id,
                  predicate,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::DeclareFunction::build_template(gc, template)
        }
        NodeKind::DeclareComponent => {
          let id = cvt_node_ptr(cvt, gc, hermes_get_DeclareComponent_id(n));
          let params = cvt_node_list(cvt, gc, hermes_get_DeclareComponent_params(n));
          let rest = cvt_node_ptr_opt(cvt, gc, hermes_get_DeclareComponent_rest(n));
          let type_parameters = cvt_node_ptr_opt(cvt, gc, hermes_get_DeclareComponent_typeParameters(n));
          let renders_type = cvt_node_ptr_opt(cvt, gc, hermes_get_DeclareComponent_rendersType(n));
          let mut template = ast::template::DeclareComponent {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  id,
                  params,
                  rest,
                  type_parameters,
                  renders_type,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::DeclareComponent::build_template(gc, template)
        }
        NodeKind::DeclareVariable => {
          let id = cvt_node_ptr(cvt, gc, hermes_get_DeclareVariable_id(n));
          let kind = cvt_enum(hermes_get_DeclareVariable_kind(n));
          let mut template = ast::template::DeclareVariable {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  id,
                  kind,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::DeclareVariable::build_template(gc, template)
        }
        NodeKind::DeclareEnum => {
          let id = cvt_node_ptr(cvt, gc, hermes_get_DeclareEnum_id(n));
          let body = cvt_node_ptr(cvt, gc, hermes_get_DeclareEnum_body(n));
          let mut template = ast::template::DeclareEnum {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  id,
                  body,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::DeclareEnum::build_template(gc, template)
        }
        NodeKind::DeclareExportDeclaration => {
          let declaration = cvt_node_ptr_opt(cvt, gc, hermes_get_DeclareExportDeclaration_declaration(n));
          let specifiers = cvt_node_list(cvt, gc, hermes_get_DeclareExportDeclaration_specifiers(n));
          let source = cvt_node_ptr_opt(cvt, gc, hermes_get_DeclareExportDeclaration_source(n));
          let default = hermes_get_DeclareExportDeclaration_default(n);
          let mut template = ast::template::DeclareExportDeclaration {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  declaration,
                  specifiers,
                  source,
                  default,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::DeclareExportDeclaration::build_template(gc, template)
        }
        NodeKind::DeclareExportAllDeclaration => {
          let source = cvt_node_ptr(cvt, gc, hermes_get_DeclareExportAllDeclaration_source(n));
          let mut template = ast::template::DeclareExportAllDeclaration {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  source,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::DeclareExportAllDeclaration::build_template(gc, template)
        }
        NodeKind::DeclareModule => {
          let id = cvt_node_ptr(cvt, gc, hermes_get_DeclareModule_id(n));
          let body = cvt_node_ptr(cvt, gc, hermes_get_DeclareModule_body(n));
          let kind = cvt.cvt_label(gc, hermes_get_DeclareModule_kind(n));
          let mut template = ast::template::DeclareModule {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  id,
                  body,
                  kind,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::DeclareModule::build_template(gc, template)
        }
        NodeKind::DeclareModuleExports => {
          let type_annotation = cvt_node_ptr(cvt, gc, hermes_get_DeclareModuleExports_typeAnnotation(n));
          let mut template = ast::template::DeclareModuleExports {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  type_annotation,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::DeclareModuleExports::build_template(gc, template)
        }
        NodeKind::InterfaceExtends => {
          let id = cvt_node_ptr(cvt, gc, hermes_get_InterfaceExtends_id(n));
          let type_parameters = cvt_node_ptr_opt(cvt, gc, hermes_get_InterfaceExtends_typeParameters(n));
          let mut template = ast::template::InterfaceExtends {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  id,
                  type_parameters,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::InterfaceExtends::build_template(gc, template)
        }
        NodeKind::ClassImplements => {
          let id = cvt_node_ptr(cvt, gc, hermes_get_ClassImplements_id(n));
          let type_parameters = cvt_node_ptr_opt(cvt, gc, hermes_get_ClassImplements_typeParameters(n));
          let mut template = ast::template::ClassImplements {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  id,
                  type_parameters,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::ClassImplements::build_template(gc, template)
        }
        NodeKind::TypeAnnotation => {
          let type_annotation = cvt_node_ptr(cvt, gc, hermes_get_TypeAnnotation_typeAnnotation(n));
          let mut template = ast::template::TypeAnnotation {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  type_annotation,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::TypeAnnotation::build_template(gc, template)
        }
        NodeKind::ObjectTypeAnnotation => {
          let properties = cvt_node_list(cvt, gc, hermes_get_ObjectTypeAnnotation_properties(n));
          let indexers = cvt_node_list(cvt, gc, hermes_get_ObjectTypeAnnotation_indexers(n));
          let call_properties = cvt_node_list(cvt, gc, hermes_get_ObjectTypeAnnotation_callProperties(n));
          let internal_slots = cvt_node_list(cvt, gc, hermes_get_ObjectTypeAnnotation_internalSlots(n));
          let inexact = hermes_get_ObjectTypeAnnotation_inexact(n);
          let exact = hermes_get_ObjectTypeAnnotation_exact(n);
          let mut template = ast::template::ObjectTypeAnnotation {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  properties,
                  indexers,
                  call_properties,
                  internal_slots,
                  inexact,
                  exact,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::ObjectTypeAnnotation::build_template(gc, template)
        }
        NodeKind::ObjectTypeProperty => {
          let key = cvt_node_ptr(cvt, gc, hermes_get_ObjectTypeProperty_key(n));
          let value = cvt_node_ptr(cvt, gc, hermes_get_ObjectTypeProperty_value(n));
          let method = hermes_get_ObjectTypeProperty_method(n);
          let optional = hermes_get_ObjectTypeProperty_optional(n);
          let is_static = hermes_get_ObjectTypeProperty_static(n);
          let proto = hermes_get_ObjectTypeProperty_proto(n);
          let variance = cvt_node_ptr_opt(cvt, gc, hermes_get_ObjectTypeProperty_variance(n));
          let kind = cvt.cvt_label(gc, hermes_get_ObjectTypeProperty_kind(n));
          let mut template = ast::template::ObjectTypeProperty {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  key,
                  value,
                  method,
                  optional,
                  is_static,
                  proto,
                  variance,
                  kind,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::ObjectTypeProperty::build_template(gc, template)
        }
        NodeKind::ObjectTypeSpreadProperty => {
          let argument = cvt_node_ptr(cvt, gc, hermes_get_ObjectTypeSpreadProperty_argument(n));
          let mut template = ast::template::ObjectTypeSpreadProperty {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  argument,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::ObjectTypeSpreadProperty::build_template(gc, template)
        }
        NodeKind::ObjectTypeInternalSlot => {
          let id = cvt_node_ptr(cvt, gc, hermes_get_ObjectTypeInternalSlot_id(n));
          let value = cvt_node_ptr(cvt, gc, hermes_get_ObjectTypeInternalSlot_value(n));
          let optional = hermes_get_ObjectTypeInternalSlot_optional(n);
          let is_static = hermes_get_ObjectTypeInternalSlot_static(n);
          let method = hermes_get_ObjectTypeInternalSlot_method(n);
          let mut template = ast::template::ObjectTypeInternalSlot {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  id,
                  value,
                  optional,
                  is_static,
                  method,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::ObjectTypeInternalSlot::build_template(gc, template)
        }
        NodeKind::ObjectTypeCallProperty => {
          let value = cvt_node_ptr(cvt, gc, hermes_get_ObjectTypeCallProperty_value(n));
          let is_static = hermes_get_ObjectTypeCallProperty_static(n);
          let mut template = ast::template::ObjectTypeCallProperty {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  value,
                  is_static,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::ObjectTypeCallProperty::build_template(gc, template)
        }
        NodeKind::ObjectTypeIndexer => {
          let id = cvt_node_ptr_opt(cvt, gc, hermes_get_ObjectTypeIndexer_id(n));
          let key = cvt_node_ptr(cvt, gc, hermes_get_ObjectTypeIndexer_key(n));
          let value = cvt_node_ptr(cvt, gc, hermes_get_ObjectTypeIndexer_value(n));
          let is_static = hermes_get_ObjectTypeIndexer_static(n);
          let variance = cvt_node_ptr_opt(cvt, gc, hermes_get_ObjectTypeIndexer_variance(n));
          let mut template = ast::template::ObjectTypeIndexer {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  id,
                  key,
                  value,
                  is_static,
                  variance,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::ObjectTypeIndexer::build_template(gc, template)
        }
        NodeKind::ObjectTypeMappedTypeProperty => {
          let key_tparam = cvt_node_ptr(cvt, gc, hermes_get_ObjectTypeMappedTypeProperty_keyTparam(n));
          let prop_type = cvt_node_ptr(cvt, gc, hermes_get_ObjectTypeMappedTypeProperty_propType(n));
          let source_type = cvt_node_ptr(cvt, gc, hermes_get_ObjectTypeMappedTypeProperty_sourceType(n));
          let variance = cvt_node_ptr_opt(cvt, gc, hermes_get_ObjectTypeMappedTypeProperty_variance(n));
          let optional = cvt.cvt_string_opt(gc, hermes_get_ObjectTypeMappedTypeProperty_optional(n));
          let mut template = ast::template::ObjectTypeMappedTypeProperty {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  key_tparam,
                  prop_type,
                  source_type,
                  variance,
                  optional,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::ObjectTypeMappedTypeProperty::build_template(gc, template)
        }
        NodeKind::Variance => {
          let kind = cvt.cvt_label(gc, hermes_get_Variance_kind(n));
          let mut template = ast::template::Variance {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  kind,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::Variance::build_template(gc, template)
        }
        NodeKind::TypeParameterDeclaration => {
          let params = cvt_node_list(cvt, gc, hermes_get_TypeParameterDeclaration_params(n));
          let mut template = ast::template::TypeParameterDeclaration {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  params,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::TypeParameterDeclaration::build_template(gc, template)
        }
        NodeKind::TypeParameter => {
          let name = cvt.cvt_label(gc, hermes_get_TypeParameter_name(n));
          let bound = cvt_node_ptr_opt(cvt, gc, hermes_get_TypeParameter_bound(n));
          let variance = cvt_node_ptr_opt(cvt, gc, hermes_get_TypeParameter_variance(n));
          let default = cvt_node_ptr_opt(cvt, gc, hermes_get_TypeParameter_default(n));
          let uses_extends_bound = hermes_get_TypeParameter_usesExtendsBound(n);
          let mut template = ast::template::TypeParameter {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  name,
                  bound,
                  variance,
                  default,
                  uses_extends_bound,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::TypeParameter::build_template(gc, template)
        }
        NodeKind::TypeParameterInstantiation => {
          let params = cvt_node_list(cvt, gc, hermes_get_TypeParameterInstantiation_params(n));
          let mut template = ast::template::TypeParameterInstantiation {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  params,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::TypeParameterInstantiation::build_template(gc, template)
        }
        NodeKind::TypeCastExpression => {
          let expression = cvt_node_ptr(cvt, gc, hermes_get_TypeCastExpression_expression(n));
          let type_annotation = cvt_node_ptr(cvt, gc, hermes_get_TypeCastExpression_typeAnnotation(n));
          let mut template = ast::template::TypeCastExpression {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  expression,
                  type_annotation,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::TypeCastExpression::build_template(gc, template)
        }
        NodeKind::InferredPredicate => {
          let mut template = ast::template::InferredPredicate {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::InferredPredicate::build_template(gc, template)
        }
        NodeKind::DeclaredPredicate => {
          let value = cvt_node_ptr(cvt, gc, hermes_get_DeclaredPredicate_value(n));
          let mut template = ast::template::DeclaredPredicate {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  value,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::DeclaredPredicate::build_template(gc, template)
        }
        NodeKind::EnumDeclaration => {
          let id = cvt_node_ptr(cvt, gc, hermes_get_EnumDeclaration_id(n));
          let body = cvt_node_ptr(cvt, gc, hermes_get_EnumDeclaration_body(n));
          let mut template = ast::template::EnumDeclaration {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  id,
                  body,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::EnumDeclaration::build_template(gc, template)
        }
        NodeKind::EnumStringBody => {
          let members = cvt_node_list(cvt, gc, hermes_get_EnumStringBody_members(n));
          let explicit_type = hermes_get_EnumStringBody_explicitType(n);
          let has_unknown_members = hermes_get_EnumStringBody_hasUnknownMembers(n);
          let mut template = ast::template::EnumStringBody {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  members,
                  explicit_type,
                  has_unknown_members,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::EnumStringBody::build_template(gc, template)
        }
        NodeKind::EnumNumberBody => {
          let members = cvt_node_list(cvt, gc, hermes_get_EnumNumberBody_members(n));
          let explicit_type = hermes_get_EnumNumberBody_explicitType(n);
          let has_unknown_members = hermes_get_EnumNumberBody_hasUnknownMembers(n);
          let mut template = ast::template::EnumNumberBody {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  members,
                  explicit_type,
                  has_unknown_members,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::EnumNumberBody::build_template(gc, template)
        }
        NodeKind::EnumBooleanBody => {
          let members = cvt_node_list(cvt, gc, hermes_get_EnumBooleanBody_members(n));
          let explicit_type = hermes_get_EnumBooleanBody_explicitType(n);
          let has_unknown_members = hermes_get_EnumBooleanBody_hasUnknownMembers(n);
          let mut template = ast::template::EnumBooleanBody {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  members,
                  explicit_type,
                  has_unknown_members,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::EnumBooleanBody::build_template(gc, template)
        }
        NodeKind::EnumSymbolBody => {
          let members = cvt_node_list(cvt, gc, hermes_get_EnumSymbolBody_members(n));
          let has_unknown_members = hermes_get_EnumSymbolBody_hasUnknownMembers(n);
          let mut template = ast::template::EnumSymbolBody {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  members,
                  has_unknown_members,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::EnumSymbolBody::build_template(gc, template)
        }
        NodeKind::EnumDefaultedMember => {
          let id = cvt_node_ptr(cvt, gc, hermes_get_EnumDefaultedMember_id(n));
          let mut template = ast::template::EnumDefaultedMember {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  id,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::EnumDefaultedMember::build_template(gc, template)
        }
        NodeKind::EnumStringMember => {
          let id = cvt_node_ptr(cvt, gc, hermes_get_EnumStringMember_id(n));
          let init = cvt_node_ptr(cvt, gc, hermes_get_EnumStringMember_init(n));
          let mut template = ast::template::EnumStringMember {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  id,
                  init,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::EnumStringMember::build_template(gc, template)
        }
        NodeKind::EnumNumberMember => {
          let id = cvt_node_ptr(cvt, gc, hermes_get_EnumNumberMember_id(n));
          let init = cvt_node_ptr(cvt, gc, hermes_get_EnumNumberMember_init(n));
          let mut template = ast::template::EnumNumberMember {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  id,
                  init,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::EnumNumberMember::build_template(gc, template)
        }
        NodeKind::EnumBooleanMember => {
          let id = cvt_node_ptr(cvt, gc, hermes_get_EnumBooleanMember_id(n));
          let init = cvt_node_ptr(cvt, gc, hermes_get_EnumBooleanMember_init(n));
          let mut template = ast::template::EnumBooleanMember {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  id,
                  init,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::EnumBooleanMember::build_template(gc, template)
        }
        NodeKind::ComponentParameter => {
          let name = cvt_node_ptr(cvt, gc, hermes_get_ComponentParameter_name(n));
          let local = cvt_node_ptr(cvt, gc, hermes_get_ComponentParameter_local(n));
          let shorthand = hermes_get_ComponentParameter_shorthand(n);
          let mut template = ast::template::ComponentParameter {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  name,
                  local,
                  shorthand,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::ComponentParameter::build_template(gc, template)
        }
        NodeKind::TSTypeAnnotation => {
          let type_annotation = cvt_node_ptr(cvt, gc, hermes_get_TSTypeAnnotation_typeAnnotation(n));
          let mut template = ast::template::TSTypeAnnotation {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  type_annotation,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::TSTypeAnnotation::build_template(gc, template)
        }
        NodeKind::TSAnyKeyword => {
          let mut template = ast::template::TSAnyKeyword {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::TSAnyKeyword::build_template(gc, template)
        }
        NodeKind::TSNumberKeyword => {
          let mut template = ast::template::TSNumberKeyword {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::TSNumberKeyword::build_template(gc, template)
        }
        NodeKind::TSBooleanKeyword => {
          let mut template = ast::template::TSBooleanKeyword {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::TSBooleanKeyword::build_template(gc, template)
        }
        NodeKind::TSStringKeyword => {
          let mut template = ast::template::TSStringKeyword {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::TSStringKeyword::build_template(gc, template)
        }
        NodeKind::TSSymbolKeyword => {
          let mut template = ast::template::TSSymbolKeyword {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::TSSymbolKeyword::build_template(gc, template)
        }
        NodeKind::TSVoidKeyword => {
          let mut template = ast::template::TSVoidKeyword {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::TSVoidKeyword::build_template(gc, template)
        }
        NodeKind::TSThisType => {
          let mut template = ast::template::TSThisType {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::TSThisType::build_template(gc, template)
        }
        NodeKind::TSLiteralType => {
          let literal = cvt_node_ptr(cvt, gc, hermes_get_TSLiteralType_literal(n));
          let mut template = ast::template::TSLiteralType {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  literal,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::TSLiteralType::build_template(gc, template)
        }
        NodeKind::TSIndexedAccessType => {
          let object_type = cvt_node_ptr(cvt, gc, hermes_get_TSIndexedAccessType_objectType(n));
          let index_type = cvt_node_ptr(cvt, gc, hermes_get_TSIndexedAccessType_indexType(n));
          let mut template = ast::template::TSIndexedAccessType {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  object_type,
                  index_type,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::TSIndexedAccessType::build_template(gc, template)
        }
        NodeKind::TSArrayType => {
          let element_type = cvt_node_ptr(cvt, gc, hermes_get_TSArrayType_elementType(n));
          let mut template = ast::template::TSArrayType {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  element_type,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::TSArrayType::build_template(gc, template)
        }
        NodeKind::TSTypeReference => {
          let type_name = cvt_node_ptr(cvt, gc, hermes_get_TSTypeReference_typeName(n));
          let type_parameters = cvt_node_ptr_opt(cvt, gc, hermes_get_TSTypeReference_typeParameters(n));
          let mut template = ast::template::TSTypeReference {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  type_name,
                  type_parameters,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::TSTypeReference::build_template(gc, template)
        }
        NodeKind::TSQualifiedName => {
          let left = cvt_node_ptr(cvt, gc, hermes_get_TSQualifiedName_left(n));
          let right = cvt_node_ptr_opt(cvt, gc, hermes_get_TSQualifiedName_right(n));
          let mut template = ast::template::TSQualifiedName {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  left,
                  right,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::TSQualifiedName::build_template(gc, template)
        }
        NodeKind::TSFunctionType => {
          let params = cvt_node_list(cvt, gc, hermes_get_TSFunctionType_params(n));
          let return_type = cvt_node_ptr(cvt, gc, hermes_get_TSFunctionType_returnType(n));
          let type_parameters = cvt_node_ptr_opt(cvt, gc, hermes_get_TSFunctionType_typeParameters(n));
          let mut template = ast::template::TSFunctionType {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  params,
                  return_type,
                  type_parameters,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::TSFunctionType::build_template(gc, template)
        }
        NodeKind::TSConstructorType => {
          let params = cvt_node_list(cvt, gc, hermes_get_TSConstructorType_params(n));
          let return_type = cvt_node_ptr(cvt, gc, hermes_get_TSConstructorType_returnType(n));
          let type_parameters = cvt_node_ptr_opt(cvt, gc, hermes_get_TSConstructorType_typeParameters(n));
          let mut template = ast::template::TSConstructorType {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  params,
                  return_type,
                  type_parameters,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::TSConstructorType::build_template(gc, template)
        }
        NodeKind::TSTypePredicate => {
          let parameter_name = cvt_node_ptr(cvt, gc, hermes_get_TSTypePredicate_parameterName(n));
          let type_annotation = cvt_node_ptr(cvt, gc, hermes_get_TSTypePredicate_typeAnnotation(n));
          let mut template = ast::template::TSTypePredicate {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  parameter_name,
                  type_annotation,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::TSTypePredicate::build_template(gc, template)
        }
        NodeKind::TSTupleType => {
          let element_types = cvt_node_list(cvt, gc, hermes_get_TSTupleType_elementTypes(n));
          let mut template = ast::template::TSTupleType {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  element_types,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::TSTupleType::build_template(gc, template)
        }
        NodeKind::TSTypeAssertion => {
          let type_annotation = cvt_node_ptr(cvt, gc, hermes_get_TSTypeAssertion_typeAnnotation(n));
          let expression = cvt_node_ptr(cvt, gc, hermes_get_TSTypeAssertion_expression(n));
          let mut template = ast::template::TSTypeAssertion {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  type_annotation,
                  expression,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::TSTypeAssertion::build_template(gc, template)
        }
        NodeKind::TSAsExpression => {
          let expression = cvt_node_ptr(cvt, gc, hermes_get_TSAsExpression_expression(n));
          let type_annotation = cvt_node_ptr(cvt, gc, hermes_get_TSAsExpression_typeAnnotation(n));
          let mut template = ast::template::TSAsExpression {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  expression,
                  type_annotation,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::TSAsExpression::build_template(gc, template)
        }
        NodeKind::TSParameterProperty => {
          let parameter = cvt_node_ptr(cvt, gc, hermes_get_TSParameterProperty_parameter(n));
          let accessibility = cvt.cvt_label_opt(gc, hermes_get_TSParameterProperty_accessibility(n));
          let readonly = hermes_get_TSParameterProperty_readonly(n);
          let is_static = hermes_get_TSParameterProperty_static(n);
          let export = hermes_get_TSParameterProperty_export(n);
          let mut template = ast::template::TSParameterProperty {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  parameter,
                  accessibility,
                  readonly,
                  is_static,
                  export,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::TSParameterProperty::build_template(gc, template)
        }
        NodeKind::TSTypeAliasDeclaration => {
          let id = cvt_node_ptr(cvt, gc, hermes_get_TSTypeAliasDeclaration_id(n));
          let type_parameters = cvt_node_ptr_opt(cvt, gc, hermes_get_TSTypeAliasDeclaration_typeParameters(n));
          let type_annotation = cvt_node_ptr(cvt, gc, hermes_get_TSTypeAliasDeclaration_typeAnnotation(n));
          let mut template = ast::template::TSTypeAliasDeclaration {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  id,
                  type_parameters,
                  type_annotation,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::TSTypeAliasDeclaration::build_template(gc, template)
        }
        NodeKind::TSInterfaceDeclaration => {
          let id = cvt_node_ptr(cvt, gc, hermes_get_TSInterfaceDeclaration_id(n));
          let body = cvt_node_ptr(cvt, gc, hermes_get_TSInterfaceDeclaration_body(n));
          let extends = cvt_node_list(cvt, gc, hermes_get_TSInterfaceDeclaration_extends(n));
          let type_parameters = cvt_node_ptr_opt(cvt, gc, hermes_get_TSInterfaceDeclaration_typeParameters(n));
          let mut template = ast::template::TSInterfaceDeclaration {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  id,
                  body,
                  extends,
                  type_parameters,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::TSInterfaceDeclaration::build_template(gc, template)
        }
        NodeKind::TSInterfaceHeritage => {
          let expression = cvt_node_ptr(cvt, gc, hermes_get_TSInterfaceHeritage_expression(n));
          let type_parameters = cvt_node_ptr_opt(cvt, gc, hermes_get_TSInterfaceHeritage_typeParameters(n));
          let mut template = ast::template::TSInterfaceHeritage {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  expression,
                  type_parameters,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::TSInterfaceHeritage::build_template(gc, template)
        }
        NodeKind::TSInterfaceBody => {
          let body = cvt_node_list(cvt, gc, hermes_get_TSInterfaceBody_body(n));
          let mut template = ast::template::TSInterfaceBody {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  body,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::TSInterfaceBody::build_template(gc, template)
        }
        NodeKind::TSEnumDeclaration => {
          let id = cvt_node_ptr(cvt, gc, hermes_get_TSEnumDeclaration_id(n));
          let members = cvt_node_list(cvt, gc, hermes_get_TSEnumDeclaration_members(n));
          let mut template = ast::template::TSEnumDeclaration {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  id,
                  members,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::TSEnumDeclaration::build_template(gc, template)
        }
        NodeKind::TSEnumMember => {
          let id = cvt_node_ptr(cvt, gc, hermes_get_TSEnumMember_id(n));
          let initializer = cvt_node_ptr_opt(cvt, gc, hermes_get_TSEnumMember_initializer(n));
          let mut template = ast::template::TSEnumMember {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  id,
                  initializer,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::TSEnumMember::build_template(gc, template)
        }
        NodeKind::TSModuleDeclaration => {
          let id = cvt_node_ptr(cvt, gc, hermes_get_TSModuleDeclaration_id(n));
          let body = cvt_node_ptr(cvt, gc, hermes_get_TSModuleDeclaration_body(n));
          let mut template = ast::template::TSModuleDeclaration {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  id,
                  body,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::TSModuleDeclaration::build_template(gc, template)
        }
        NodeKind::TSModuleBlock => {
          let body = cvt_node_list(cvt, gc, hermes_get_TSModuleBlock_body(n));
          let mut template = ast::template::TSModuleBlock {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  body,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::TSModuleBlock::build_template(gc, template)
        }
        NodeKind::TSModuleMember => {
          let id = cvt_node_ptr(cvt, gc, hermes_get_TSModuleMember_id(n));
          let initializer = cvt_node_ptr_opt(cvt, gc, hermes_get_TSModuleMember_initializer(n));
          let mut template = ast::template::TSModuleMember {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  id,
                  initializer,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::TSModuleMember::build_template(gc, template)
        }
        NodeKind::TSTypeParameterDeclaration => {
          let params = cvt_node_list(cvt, gc, hermes_get_TSTypeParameterDeclaration_params(n));
          let mut template = ast::template::TSTypeParameterDeclaration {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  params,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::TSTypeParameterDeclaration::build_template(gc, template)
        }
        NodeKind::TSTypeParameter => {
          let name = cvt_node_ptr(cvt, gc, hermes_get_TSTypeParameter_name(n));
          let constraint = cvt_node_ptr_opt(cvt, gc, hermes_get_TSTypeParameter_constraint(n));
          let default = cvt_node_ptr_opt(cvt, gc, hermes_get_TSTypeParameter_default(n));
          let mut template = ast::template::TSTypeParameter {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  name,
                  constraint,
                  default,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::TSTypeParameter::build_template(gc, template)
        }
        NodeKind::TSTypeParameterInstantiation => {
          let params = cvt_node_list(cvt, gc, hermes_get_TSTypeParameterInstantiation_params(n));
          let mut template = ast::template::TSTypeParameterInstantiation {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  params,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::TSTypeParameterInstantiation::build_template(gc, template)
        }
        NodeKind::TSUnionType => {
          let types = cvt_node_list(cvt, gc, hermes_get_TSUnionType_types(n));
          let mut template = ast::template::TSUnionType {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  types,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::TSUnionType::build_template(gc, template)
        }
        NodeKind::TSIntersectionType => {
          let types = cvt_node_list(cvt, gc, hermes_get_TSIntersectionType_types(n));
          let mut template = ast::template::TSIntersectionType {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  types,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::TSIntersectionType::build_template(gc, template)
        }
        NodeKind::TSTypeQuery => {
          let expr_name = cvt_node_ptr(cvt, gc, hermes_get_TSTypeQuery_exprName(n));
          let mut template = ast::template::TSTypeQuery {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  expr_name,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::TSTypeQuery::build_template(gc, template)
        }
        NodeKind::TSConditionalType => {
          let check_type = cvt_node_ptr(cvt, gc, hermes_get_TSConditionalType_checkType(n));
          let extends_type = cvt_node_ptr(cvt, gc, hermes_get_TSConditionalType_extendsType(n));
          let true_type = cvt_node_ptr(cvt, gc, hermes_get_TSConditionalType_trueType(n));
          let false_type = cvt_node_ptr(cvt, gc, hermes_get_TSConditionalType_falseType(n));
          let mut template = ast::template::TSConditionalType {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  check_type,
                  extends_type,
                  true_type,
                  false_type,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::TSConditionalType::build_template(gc, template)
        }
        NodeKind::TSTypeLiteral => {
          let members = cvt_node_list(cvt, gc, hermes_get_TSTypeLiteral_members(n));
          let mut template = ast::template::TSTypeLiteral {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  members,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::TSTypeLiteral::build_template(gc, template)
        }
        NodeKind::TSPropertySignature => {
          let key = cvt_node_ptr(cvt, gc, hermes_get_TSPropertySignature_key(n));
          let type_annotation = cvt_node_ptr_opt(cvt, gc, hermes_get_TSPropertySignature_typeAnnotation(n));
          let initializer = cvt_node_ptr_opt(cvt, gc, hermes_get_TSPropertySignature_initializer(n));
          let optional = hermes_get_TSPropertySignature_optional(n);
          let computed = hermes_get_TSPropertySignature_computed(n);
          let readonly = hermes_get_TSPropertySignature_readonly(n);
          let is_static = hermes_get_TSPropertySignature_static(n);
          let export = hermes_get_TSPropertySignature_export(n);
          let mut template = ast::template::TSPropertySignature {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  key,
                  type_annotation,
                  initializer,
                  optional,
                  computed,
                  readonly,
                  is_static,
                  export,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::TSPropertySignature::build_template(gc, template)
        }
        NodeKind::TSMethodSignature => {
          let key = cvt_node_ptr(cvt, gc, hermes_get_TSMethodSignature_key(n));
          let params = cvt_node_list(cvt, gc, hermes_get_TSMethodSignature_params(n));
          let return_type = cvt_node_ptr_opt(cvt, gc, hermes_get_TSMethodSignature_returnType(n));
          let computed = hermes_get_TSMethodSignature_computed(n);
          let mut template = ast::template::TSMethodSignature {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  key,
                  params,
                  return_type,
                  computed,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::TSMethodSignature::build_template(gc, template)
        }
        NodeKind::TSIndexSignature => {
          let parameters = cvt_node_list(cvt, gc, hermes_get_TSIndexSignature_parameters(n));
          let type_annotation = cvt_node_ptr_opt(cvt, gc, hermes_get_TSIndexSignature_typeAnnotation(n));
          let mut template = ast::template::TSIndexSignature {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  parameters,
                  type_annotation,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::TSIndexSignature::build_template(gc, template)
        }
        NodeKind::TSCallSignatureDeclaration => {
          let params = cvt_node_list(cvt, gc, hermes_get_TSCallSignatureDeclaration_params(n));
          let return_type = cvt_node_ptr_opt(cvt, gc, hermes_get_TSCallSignatureDeclaration_returnType(n));
          let mut template = ast::template::TSCallSignatureDeclaration {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  params,
                  return_type,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::TSCallSignatureDeclaration::build_template(gc, template)
        }
        NodeKind::TSModifiers => {
          let accessibility = cvt.cvt_label(gc, hermes_get_TSModifiers_accessibility(n));
          let readonly = hermes_get_TSModifiers_readonly(n);
          let mut template = ast::template::TSModifiers {
              metadata: ast::TemplateMetadata {range, ..Default::default()},
                  accessibility,
                  readonly,
          };
          template.metadata.range.end = if nr.source_range.is_empty() { template.metadata.range.start } else { cvt.cvt_smloc(nr.source_range.end.pred()) };
          ast::builder::TSModifiers::build_template(gc, template)
        }
        _ => {
          cvt.report_invalid_node(gc, n, range);
          let template = ast::template::Empty {
            metadata: ast::TemplateMetadata {range, ..Default::default()}
          };
          ast::builder::Empty::build_template(gc, template)
        }
    };

    res
}