translateCompartmentMap = (compartments, sources, compartmentRenames) => {
  const result = create(null);
  for (const compartmentName of keys(compartmentRenames)) {
    const compartment = compartments[compartmentName];
    const { name, label, retained: compartmentRetained, policy } = compartment;
    if (compartmentRetained) {
      // rename module compartments
      /** @type {Record<string, ModuleDescriptor>} */
      const modules = create(null);
      const compartmentModules = compartment.modules;
      if (compartment.modules) {
        for (const name of keys(compartmentModules).sort()) {
          const { retained: moduleRetained, ...retainedModule } =
            compartmentModules[name];
          if (moduleRetained) {
            if (retainedModule.compartment !== undefined) {
              modules[name] = {
                ...retainedModule,
                compartment: compartmentRenames[retainedModule.compartment],
              };
            } else {
              modules[name] = retainedModule;
            }
          }
        }
      }

      // integrate sources into modules
      const compartmentSources = sources[compartmentName];
      if (compartmentSources) {
        for (const name of keys(compartmentSources).sort()) {
          const source = compartmentSources[name];
          const { location, parser, exit, sha512, deferredError } = source;
          if (location !== undefined) {
            modules[name] = {
              location,
              parser,
              sha512,
            };
          } else if (exit !== undefined) {
            modules[name] = {
              exit,
            };
          } else if (deferredError !== undefined) {
            modules[name] = {
              deferredError,
            };
          }
        }
      }

      result[compartmentRenames[compartmentName]] = {
        name,
        label,
        location: compartmentRenames[compartmentName],
        modules,
        policy,
        // `scopes`, `types`, and `parsers` are not necessary since every
        // loadable module is captured in `modules`.
      };
    }
  }

  return result;
}
@param {Record<string, CompartmentDescriptor>} compartments
@param {Sources} sources
@param {Record<string, string>} compartmentRenames