function checkProgramForMaxLength(node) {
      const programNode = node
      const templateBody = node.templateBody

      // setup tokens
      const scriptTokens = sourceCode.ast.tokens
      const scriptComments = sourceCode.getAllComments()

      if (sourceCode.parserServices.getTemplateBodyTokenStore && templateBody) {
        const tokenStore = sourceCode.parserServices.getTemplateBodyTokenStore()

        const templateTokens = tokenStore.getTokens(templateBody, {
          includeComments: true
        })

        if (templateBody.range[0] < programNode.range[0]) {
          tokens.push(...templateTokens, ...scriptTokens)
        } else {
          tokens.push(...scriptTokens, ...templateTokens)
        }
      } else {
        tokens.push(...scriptTokens)
      }

      if (ignoreComments || maxCommentLength || ignoreTrailingComments) {
        // list of comments to ignore
        if (templateBody) {
          if (templateBody.range[0] < programNode.range[0]) {
            comments.push(...templateBody.comments, ...scriptComments)
          } else {
            comments.push(...scriptComments, ...templateBody.comments)
          }
        } else {
          comments.push(...scriptComments)
        }
      }

      /** @type {Range | undefined} */
      let scriptLinesRange
      if (scriptTokens.length > 0) {
        scriptLinesRange =
          scriptComments.length > 0
            ? [
                Math.min(
                  scriptTokens[0].loc.start.line,
                  scriptComments[0].loc.start.line
                ),
                Math.max(
                  scriptTokens[scriptTokens.length - 1].loc.end.line,
                  scriptComments[scriptComments.length - 1].loc.end.line
                )
              ]
            : [
                scriptTokens[0].loc.start.line,
                scriptTokens[scriptTokens.length - 1].loc.end.line
              ]
      } else if (scriptComments.length > 0) {
        scriptLinesRange = [
          scriptComments[0].loc.start.line,
          scriptComments[scriptComments.length - 1].loc.end.line
        ]
      }
      const templateLinesRange = templateBody && [
        templateBody.loc.start.line,
        templateBody.loc.end.line
      ]

      // split (honors line-ending)
      const lines = sourceCode.lines

      const strings = getAllStrings()
      const stringsByLine = groupByLineNumber(strings)

      const templateLiterals = getAllTemplateLiterals()
      const templateLiteralsByLine = groupByLineNumber(templateLiterals)

      const regExpLiterals = getAllRegExpLiterals()
      const regExpLiteralsByLine = groupByLineNumber(regExpLiterals)

      const htmlAttributeValuesByLine = groupByLineNumber(htmlAttributeValues)

      const htmlTextContents = getAllHTMLTextContents()
      const htmlTextContentsByLine = groupByLineNumber(htmlTextContents)

      const commentsByLine = groupByLineNumber(comments)

      for (const [i, line] of lines.entries()) {
        // i is zero-indexed, line numbers are one-indexed
        const lineNumber = i + 1

        const inScript =
          scriptLinesRange &&
          scriptLinesRange[0] <= lineNumber &&
          lineNumber <= scriptLinesRange[1]
        const inTemplate =
          templateLinesRange &&
          templateLinesRange[0] <= lineNumber &&
          lineNumber <= templateLinesRange[1]
        // check if line is inside a script or template.
        if (!inScript && !inTemplate) {
          // out of range.
          continue
        }
        const maxLength = Math.max(
          inScript ? scriptMaxLength : 0,
          inTemplate ? templateMaxLength : 0
        )

        if (
          (ignoreStrings && stringsByLine[lineNumber]) ||
          (ignoreTemplateLiterals && templateLiteralsByLine[lineNumber]) ||
          (ignoreRegExpLiterals && regExpLiteralsByLine[lineNumber]) ||
          (ignoreHTMLAttributeValues &&
            htmlAttributeValuesByLine[lineNumber]) ||
          (ignoreHTMLTextContents && htmlTextContentsByLine[lineNumber])
        ) {
          // ignore this line
          continue
        }

        /*
         * if we're checking comment length; we need to know whether this
         * line is a comment
         */
        let lineIsComment = false
        let textToMeasure

        /*
         * comments to check.
         */
        if (commentsByLine[lineNumber]) {
          const commentList = [...commentsByLine[lineNumber]]

          let comment = commentList.pop() || null

          if (isFullLineComment(line, lineNumber, comment)) {
            lineIsComment = true
            textToMeasure = line
          } else if (
            ignoreTrailingComments &&
            isTrailingComment(line, lineNumber, comment)
          ) {
            textToMeasure = stripTrailingComment(line, comment)

            // ignore multiple trailing comments in the same line
            comment = commentList.pop() || null

            while (isTrailingComment(textToMeasure, lineNumber, comment)) {
              textToMeasure = stripTrailingComment(textToMeasure, comment)
            }
          } else {
            textToMeasure = line
          }
        } else {
          textToMeasure = line
        }

        if (
          (ignorePattern && ignorePattern.test(textToMeasure)) ||
          (ignoreUrls && URL_REGEXP.test(textToMeasure))
        ) {
          // ignore this line
          continue
        }

        const lineLength = computeLineLength(textToMeasure, tabWidth)
        const commentLengthApplies = lineIsComment && maxCommentLength

        if (lineIsComment && ignoreComments) {
          continue
        }

        if (commentLengthApplies) {
          if (lineLength > maxCommentLength) {
            context.report({
              node,
              loc: { line: lineNumber, column: 0 },
              messageId: 'maxComment',
              data: {
                lineLength,
                maxCommentLength
              }
            })
          }
        } else if (lineLength > maxLength) {
          context.report({
            node,
            loc: { line: lineNumber, column: 0 },
            messageId: 'max',
            data: {
              lineLength,
              maxLength
            }
          })
        }
      }
    }
Check the program for max length
@param {Program} node Node to examine
@returns {void}
@private