function categorizeLeafWithUnchangedText(
  newLeaf,
  legacyLeaves,
  newStringByCategory,
  newPhrase,
  legacyPhrase,
) /*: void */ {
  const legacyLeavesWithSameText = Object.entries(legacyLeaves).filter(
    ([_, {text: legacyText}]) => newLeaf[1].text === legacyText,
  );
  if (legacyLeavesWithSameText.length !== 1) {
    const err = new Error(
      'A string extracted from OSS script should have at most one legacy string with the same text.',
    );
    err.stack;
    throw err;
  }

  const legacyLeaf = legacyLeavesWithSameText[0];
  const [legacyHash, {text: legacyText}] = legacyLeaf;
  let {desc: legacyDesc} = legacyLeaf[1];
  const [hash, {text}] = newLeaf;
  let {desc} = newLeaf[1];
  if (hash === legacyHash) {
    return;
  }

  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:
  // When generating descriptions, the legacy script does not respect
  // the explicit whitespaces in front of inner strings. On the contrary, explicit
  // whitespaces are always included in the description by the new string collection script.
  if (
    (desc = desc.replace(/\s*{=/g, '{=')) ===
    (legacyDesc = legacyDesc.replace(/\s*{=/g, '{='))
  ) {
    newStringByCategory[
      CATEGORY.UPDATED_DESC_DUE_TO_SPACES_IN_FRONT_OF_INNER_STRINGS
    ][hash] = result;
    return;
  }
  // CASE 2:
  // New string is created due to added variations in description.
  const {m: mNew} = newPhrase.jsfbt;
  const {m: mOld} = legacyPhrase.jsfbt;
  const innerStringTokenRegex = /\s*{=[^}]+}\s*/g;
  if (
    mNew.length > mOld.length ||
    // This is the case where the `newPhrase` is an inner string and it contains variations
    desc.replace(innerStringTokenRegex, '') ===
      legacyDesc.replace(innerStringTokenRegex, '')
  ) {
    if (legacyDesc.indexOf('{=}') !== -1) {
      newStringByCategory[
        CATEGORY.UPDATED_DESC_DUE_TO_HIDDEN_TOKEN_AND_ADDED_VARIATIONS
      ][hash] = result;
    } else {
      newStringByCategory[CATEGORY.UPDATED_DESC_DUE_TO_VARIATIONS][hash] =
        result;
    }
    return;
  }
  // CASE 3:
  // Fbt:param construct are mis-represented as "{=}" in the string description
  // by the legacy script. In the latest version, "{=}" is replaced with the
  // actual param name, which causes new descriptions to be generated.
  if (legacyDesc.indexOf('{=}') !== -1) {
    newStringByCategory[
      CATEGORY.UPDATED_DESC_DUE_TO_HIDDEN_FBT_PARAM_TOKEN_NAME
    ][hash] = result;
    return;
  }
  // CASE 4:
  // Other small un-categorizable changes
  newStringByCategory[CATEGORY.UPDATED_DESC_DUE_TO_OTHER_REASON][hash] = {
    ...result,
    legacyJsfbt: legacyPhrase.jsfbt,
  };
}
Categorize a string(`newLeaf`) whose `text` is identical to an existing string but
`desc` is potentially different