docs: public boolean exec(TemplateNode template) {
  
      boolean hasOptional = false;
      for (TemplateParam param : template.getParams()) {
        if (param.isRequired()) {
          // If there exists a required param, then data should already be defined (no need to
          // ensure).
          return false;
        } else {
          hasOptional = true;
        }
      }
      if (hasOptional) {
        // If all params are optional (and there is at least one), then we need to ensure data is
        // defined.  This is because the only legal way to have an optional param is if you reference
        // it somewhere in the template, so there is no need to check.
        return true;
      }
      // If we get here then the template has no declared params and we are observing a v1 compatible
      // template.  Search for things that could be data references:
      // * possibleParams
      // * data=All calls
      // others?
      return new AbstractNodeVisitor<Node, Boolean>() {
        boolean shouldEnsureDataIsDefined;
  
        @Override
        public Boolean exec(Node node) {
          visit(node);
          return shouldEnsureDataIsDefined;
        }
  
        @Override
        public void visit(Node node) {
          if (node instanceof VarRefNode) {
            VarRefNode varRefNode = (VarRefNode) node;
            VarDefn var = varRefNode.getDefnDecl();
            // Don't include injected params in this analysis
            if (varRefNode.isPossibleHeaderVar()
                && var.kind() != VarDefn.Kind.STATE
                && (var.kind() != VarDefn.Kind.PARAM // a soydoc param -> not ij
                    || !((TemplateParam) var).isInjected())) { // an {@param but not {@inject
              shouldEnsureDataIsDefined = true;
              return;
            }
          }
          if (node instanceof CallNode) {
            if (((CallNode) node).isPassingAllData()) {
              shouldEnsureDataIsDefined = true;
              return;
            }
          }
          if (node instanceof ParentNode) {
            for (Node child : ((ParentNode<?>) node).getChildren()) {
              visit(child);
              if (shouldEnsureDataIsDefined) {
                return;
              }
            }
          }
          if (node instanceof ExprHolderNode) {
            for (ExprRootNode expr : ((ExprHolderNode) node).getExprList()) {
              visit(expr);
              if (shouldEnsureDataIsDefined) {
                return;
              }
            }
          }
        }
      }.exec(template);
    }