docs: @Override
    protected void visitTemplateNode(TemplateNode node) {
      String templateName = node.getTemplateName();
      String partialName = node.getPartialTemplateName().substring(1);
      String alias;
  
      if (jsSrcOptions.shouldGenerateGoogModules() && node instanceof TemplateDelegateNode) {
        alias = partialName;
      } else {
        alias = templateAliases.get(templateName);
      }
      Expression aliasExp = dottedIdNoRequire(alias);
  
      // TODO(lukes): reserve all the namespace prefixes that are in scope
      // TODO(lukes): use this for all local variable declarations
      UniqueNameGenerator nameGenerator = JsSrcNameGenerators.forLocalVariables();
      CodeChunk.Generator codeGenerator = CodeChunk.Generator.create(nameGenerator);
      templateTranslationContext =
          TranslationContext.of(
              SoyToJsVariableMappings.forNewTemplate(), codeGenerator, nameGenerator);
      genJsExprsVisitor =
          genJsExprsVisitorFactory.create(templateTranslationContext, templateAliases, errorReporter);
      assistantForMsgs = null;
  
      JsDoc jsDoc = generateFunctionJsDoc(node, alias);
      Expression function = Expression.function(jsDoc, generateFunctionBody(node, alias));
      ImmutableList.Builder<Statement> declarations = ImmutableList.builder();
  
      if (jsSrcOptions.shouldGenerateGoogModules()) {
        declarations.add(VariableDeclaration.builder(alias).setJsDoc(jsDoc).setRhs(function).build());
        // don't export deltemplates or private templates
        if (!(node instanceof TemplateDelegateNode) && node.getVisibility() == Visibility.PUBLIC) {
          declarations.add(assign(JsRuntime.EXPORTS.dotAccess(partialName), aliasExp));
        }
      } else {
        declarations.add(Statement.assign(aliasExp, function, jsDoc));
      }
  
      // ------ Add the @typedef of opt_data. ------
      if (!node.getParams().isEmpty()) {
        declarations.add(
            aliasExp
                .dotAccess("Params")
                .asStatement(
                    JsDoc.builder()
                        .addParameterizedAnnotation("typedef", genParamsRecordType(node))
                        .build()));
      }
  
      // ------ Add the fully qualified template name to the function to use in debug code. ------
      declarations.add(
          ifStatement(
                  GOOG_DEBUG,
                  assign(aliasExp.dotAccess("soyTemplateName"), stringLiteral(templateName)))
              .build());
  
      // ------ If delegate template, generate a statement to register it. ------
      if (node instanceof TemplateDelegateNode) {
        TemplateDelegateNode nodeAsDelTemplate = (TemplateDelegateNode) node;
        declarations.add(
            SOY_REGISTER_DELEGATE_FN
                .call(
                    SOY_GET_DELTEMPLATE_ID.call(
                        stringLiteral(delTemplateNamer.getDelegateName(nodeAsDelTemplate))),
                    stringLiteral(nodeAsDelTemplate.getDelTemplateVariant()),
                    number(nodeAsDelTemplate.getDelPriority().getValue()),
                    aliasExp)
                .asStatement());
      }
  
      jsCodeBuilder.append(Statement.of(declarations.build()));
    }