function categorizeLeafWithUpdatedText(
  newLeaf,
  legacyLeaves,
  newStringByCategory,
  newPhrase,
  legacyPhrase,
) /*: void */ {
  const innerStringTokenRegex = /{=[^}]+}/g;
  const spaceRegex = /\s/g;
  const {m: mNew} = newPhrase.jsfbt;
  const {m: mOld} = legacyPhrase.jsfbt;
  const [hash, {desc, text}] = newLeaf;
  for (const [
    legacyHash,
    {desc: legacyDesc, text: legacyText},
  ] of Object.entries(legacyLeaves)) {
    const result = {
      legacyHash,
      text,
      legacyText,
      desc,
      legacyDesc,
      hashKey: newPhrase.hash_key,
      legacyHashKey: legacyPhrase.hash_key,
      project: newPhrase.project,
      filepath: newPhrase.filepath,
      lineBeg: newPhrase.line_beg,
      lineEnd: newPhrase.line_end,
    };

    // CASE 1:
    // Inner string token is mis-represented as "{=}" in legacy string.
    // Consider this fbt:
    if (
      legacyText.indexOf('{=}') !== -1 &&
      // After fixing the hidden token {=}, the legacy text and new text should be identical
      text.replace(innerStringTokenRegex, '') === legacyText.replace(/{=}/g, '')
    ) {
      if (mNew.length > mOld.length) {
        // If new phrase has new variations, they must be in an inner string
        newStringByCategory[
          CATEGORY.UPDATED_TEXT_DUE_TO_REPLACING_HIDDEN_TOKEN_WITH_VARIATIONS
        ][hash] = result;
      } else {
        newStringByCategory[
          CATEGORY.UPDATED_TEXT_DUE_TO_HIDDEN_INNER_STRING_TOKEN_NAME
        ][hash] = result;
      }
      return;
    }

    // CASE 2:
    // The new string differs from the legacy string due to updated text variation.
    // When an fbt callsite have string variation arguments nested inside of inner strings,
    // new string collection script will extract more variation strings in this scenario.
    if (
      text.replace(innerStringTokenRegex, '') ===
      // With inner string and hidden token removed, the legacy string should be the same as inner string
      legacyText.replace(innerStringTokenRegex, '').replace(/{=}/g, '')
    ) {
      newStringByCategory[
        CATEGORY.UPDATED_TEXT_DUE_TO_VARIATIONS_IN_INNER_STRING
      ][hash] = result;
      return;
    }

    // CASE 3:
    // Some legacy strings have leading and trailing space(s), whereas new strings are always
    // trimmed on both ends.
    if (text === legacyText.trim()) {
      newStringByCategory[
        CATEGORY.UPDATED_TEXT_DUE_TO_LEADING_OR_TRIALING_SPACE
      ][hash] = result;
      return;
    }

    // CASE 4:
    // White spaces (including \t and \n) were sometimes not preserved in old
    // string.
    if (text.replace(spaceRegex, '') === legacyText.replace(spaceRegex, '')) {
      newStringByCategory[
        CATEGORY.UPDATED_TEXT_DUE_TO_FIXING_UNPRESERVED_WHITESPACES
      ][hash] = result;
      return;
    }
  }
  newStringByCategory[CATEGORY.UPDATED_TEXT_DUE_TO_OTHER_REASON][hash] = {
    text,
    desc,
    legacyLeaves,
  };
}
Categorize a string(`newLeaf`) whose `text` is updated