function keysFromBundle(method, bundle, keys, translations) {
  const messageErrors = [];
  const missingIds = new Set();

  keys.forEach(({ id, args }, i) => {
    if (translations[i] !== undefined) {
      return;
    }

    let message = bundle.getMessage(id);
    if (message) {
      messageErrors.length = 0;
      translations[i] = method(bundle, messageErrors, message, args);
      if (messageErrors.length > 0 && typeof console !== "undefined") {
        const locale = bundle.locales[0];
        const errors = messageErrors.join(", ");
        console.warn(
          `[fluent][resolver] errors in ${locale}/${id}: ${errors}.`
        );
      }
    } else {
      missingIds.add(id);
    }
  });

  return missingIds;
}
This function is an inner function for `Localization.formatWithFallback`.

It takes a `FluentBundle`, list of l10n-ids and a method to be used for
key resolution (either `valueFromBundle` or `messageFromBundle`) and
optionally a value returned from `keysFromBundle` executed against
another `FluentBundle`.

The idea here is that if the previous `FluentBundle` did not resolve
all keys, we're calling this function with the next context to resolve
the remaining ones.

In the function, we loop over `keys` and check if we have the `prev`
passed and if it has an error entry for the position we're in.

If it doesn't, it means that we have a good translation for this key and
we return it. If it does, we'll try to resolve the key using the passed
`FluentBundle`.

In the end, we fill the translations array, and return the Set with
missing ids.

See `Localization.formatWithFallback` for more info on how this is used.

@param {Function}       method
@param {FluentBundle} bundle
@param {Array<string>}  keys
@param {{Array<{value: string, attributes: Object}>}} translations

@returns {Set<string>}
@private