function computeTokenLength(content, features) {
  let totalTokenLength = 0;
  let isInSinglelineComment = false;
  let isInMultilineComment = false;
  let isInLicenseComment = false;
  let isInString = false;
  let isInRegex = false;
  let isInRegexCharacterClass = false;
  let stringOpenChar = null;

  /**
   * Acts as stack for brace tracking.
   * @type {('templateBrace'|'normalBrace')[]}
   */
  const templateLiteralDepth = [];

  for (let i = 0; i < content.length; i++) {
    const twoChars = content.substr(i, 2);
    const char = twoChars.charAt(0);

    const isWhitespace = char === ' ' || char === '\n' || char === '\t';
    const isAStringOpenChar = char === `'` || char === '"' || char === '`';

    if (isInSinglelineComment) {
      if (char === '\n') {
        // End the comment when you hit a newline
        isInSinglelineComment = false;
      }
    } else if (isInMultilineComment) {
      // License comments count
      if (isInLicenseComment) totalTokenLength++;

      if (twoChars === '*/') {
        // License comments count, account for the '/' character we're skipping over
        if (isInLicenseComment) totalTokenLength++;
        // End the comment when we hit the closing sequence
        isInMultilineComment = false;
        // Skip over the '/' character since we've already processed it
        i++;
      }
    } else if (isInString) {
      // String characters count
      totalTokenLength++;

      if (stringOpenChar === '`' && twoChars === '${') {
        // Start new template literal
        templateLiteralDepth.push('templateBrace');
        isInString = false;
        totalTokenLength++;
        i++;
      } else if (char === '\\') {
        // Skip over any escaped characters
        totalTokenLength++;
        i++;
      } else if (char === stringOpenChar) {
        // End the string when we hit the same stringOpenCharacter
        isInString = false;
        // console.log(i, 'exiting string', stringOpenChar)
      }
    } else if (isInRegex) {
      // Regex characters count
      totalTokenLength++;

      if (char === '\\') {
        // Skip over any escaped characters
        totalTokenLength++;
        i++;
      } else if (char === '[') {
        // Register that we're entering a character class so we don't leave the regex prematurely
        isInRegexCharacterClass = true;
      } else if (char === ']' && isInRegexCharacterClass) {
        // Register that we're exiting the character class
        isInRegexCharacterClass = false;
      } else if (char === '/' && !isInRegexCharacterClass) {
        // End the string when we hit the regex close character
        isInRegex = false;
        // console.log(i, 'leaving regex', char)
      }
    } else {
      // We're not in any particular token mode, look for the start of different
      if (twoChars === '/*') {
        // Start the multi-line comment
        isInMultilineComment = true;
        // Check if it's a license comment so we know whether to count it
        isInLicenseComment = content.charAt(i + 2) === '!';
        // += 2 because we are processing 2 characters, not just 1
        if (isInLicenseComment) totalTokenLength += 2;
        // Skip over the '*' character since we've already processed it
        i++;
      } else if (twoChars === '//' && features.singlelineComments) {
        // Start the single-line comment
        isInSinglelineComment = true;
        isInMultilineComment = false;
        isInLicenseComment = false;
        // Skip over the second '/' character since we've already processed it
        i++;
      } else if (char === '/' && features.regex && hasPunctuatorBefore(content, i)) {
        // Start the regex
        isInRegex = true;
        // Regex characters count
        totalTokenLength++;
      } else if (char === '{' && templateLiteralDepth.length) {
        // Start normal code brace if inside a template literal
        templateLiteralDepth.push('normalBrace');
        totalTokenLength++;
      } else if (char === '}' && templateLiteralDepth.length) {
        // End one template literal if closing brace is for a template literal
        if (templateLiteralDepth[templateLiteralDepth.length - 1] === 'templateBrace') {
          isInString = true;
          stringOpenChar = '`';
        }
        templateLiteralDepth.pop();
        totalTokenLength++;
      } else if (isAStringOpenChar) {
        // Start the string
        isInString = true;
        // Save the open character for later so we know when to close it
        stringOpenChar = char;
        // String characters count
        totalTokenLength++;
      } else if (!isWhitespace) {
        // All non-whitespace characters count
        totalTokenLength++;
      }
    }
  }

  // If the content contained unbalanced comments, it's either invalid or we had a parsing error.
  // Report the token length as the entire string so it will be ignored.
  if (isInMultilineComment || isInString) {
    return content.length;
  }

  return totalTokenLength;
}
@param {string} content
@param {{singlelineComments: boolean, regex: boolean}} features