function fbtCallsite()

in runtime/shared/fbt.js [101:207]


function fbtCallsite(
  inputTable: FbtRuntimeInput,
  inputArgs: ?FbtTableArgs,
  options: ?FbtInputOpts,
): Fbt {
  // TODO T61652022: Remove this when no longer used in fbsource
  // $FlowFixMe[sketchy-null-string]
  if ((options?.hk || options?.ehk) && jsonExportMode) {
    /* $FlowFixMe[incompatible-return] : breaking typing because this should
     * never happen */
    return {
      text: inputTable,
      fbt: true,
      hashKey: options.hk,
    };
  }

  // Adapt the input payload to the translated table and arguments we expect
  //
  // WWW: The payload is ready, as-is, and is pre-translated UNLESS we detect
  //      the magic BINAST string which needs to be stripped if it exists.
  //
  // RN: we look up our translated table via the hash key (options.hk) and
  //     flattened enum hash key (options.ehk), which partially resolves the
  //     translation for the enums (should they exist).
  //
  // OSS: The table is the English payload, and, by default, we lookup the
  //      translated payload via FbtTranslations
  let {args, table: pattern} = FbtHooks.getTranslatedInput({
    table: inputTable,
    args: inputArgs,
    options,
  });

  // [fbt_impressions]
  // If this is a string literal (no tokens to substitute) then 'args' is empty
  // and the logic will skip the table traversal.

  // [table traversal]
  // At this point we assume that table is a hash (possibly nested) that we
  // need to traverse in order to pick the correct string, based on the
  // args that follow.
  let allSubstitutions = {};

  if (pattern.__vcg != null) {
    args = args || [];
    const {GENDER} = FbtHooks.getViewerContext();
    const variation = getGenderVariations(GENDER);
    args.unshift(FbtTableAccessor.getGenderResult(variation, null, GENDER));
  }

  if (args) {
    if (typeof pattern !== 'string') {
      // On mobile, table can be accessed at the native layer when fetching
      // translations. If pattern is not a string here, table has not been accessed
      pattern = FbtTable.access(pattern, args, 0);
    }

    allSubstitutions = getAllSubstitutions(args);
    invariant(pattern !== null, 'Table access failed');
  }

  let patternString, patternHash;
  if (Array.isArray(pattern)) {
    // [fbt_impressions]
    // When logging of string impressions is enabled, the string and its hash
    // are packaged in an array. We want to log the hash
    patternString = pattern[0];
    patternHash = pattern[1];
    // Append '1_' for appid's prepended to our i18n hash
    // (see intl_get_application_id)
    const stringID = '1_' + patternHash;
    if (overrides[stringID] != null && overrides[stringID] !== '') {
      patternString = overrides[stringID];
      FbtHooks.onTranslationOverride(patternHash);
    }
    FbtHooks.logImpression(patternHash);
  } else if (typeof pattern === 'string') {
    patternString = pattern;
  } else {
    throw new Error(
      'Table access did not result in string: ' +
        (pattern === undefined ? 'undefined' : JSON.stringify(pattern)) +
        ', Type: ' +
        typeof pattern,
    );
  }

  const cachedFbt = cachedFbtResults[patternString];
  const hasSubstitutions = _hasKeys(allSubstitutions);

  if (cachedFbt && !hasSubstitutions) {
    return cachedFbt;
  } else {
    const fbtContent = substituteTokens(patternString, allSubstitutions);
    // Use this._wrapContent voluntarily so that it can be overwritten in fbs.js
    const result = (this._wrapContent: typeof wrapContent)(
      fbtContent,
      patternString,
      patternHash,
    );
    if (!hasSubstitutions) {
      cachedFbtResults[patternString] = result;
    }
    return result;
  }
}