How does the events dispatcher map to map_save to a callback function? MigrateEvents.php contains an event definition like this:

/**
 * Name of the event fired when saving to a migration's map.
 *
 * This event allows modules to perform an action whenever the disposition of
 * an item being migrated is saved to the map table. The event listener method
 * receives a \Drupal\migrate\Event\MigrateMapSaveEvent instance.
 *
 * @Event
 *
 * @see \Drupal\migrate\Event\MigrateMapSaveEvent
 *
 * @var string
 */
const MAP_SAVE = 'migrate.map_save';


If I grep the codebase for map_save, there is no other reference to it. What mechanism does Drupal/Symfony use to know the callback to call?
This event is fired by \Drupal\migrate\Plugin\migrate\id_map\Sql::saveIdMapping().

$this-&gt;eventDispatcher-&gt;dispatch(MigrateEvents::MAP_SAVE, new MigrateMapSaveEvent($this, $keys + $fields));


To listen and react to this event you need to add a new service that implements \Symfony\Component\EventDispatcher\EventSubscriberInterface and tag it with 'event_subscriber'.

This is what you find in content_translation.services.yml.

content_translation.updates_manager:
  class: Drupal\content_translation\ContentTranslationUpdatesManager
    arguments: ['@entity.manager', '@entity.definition_update_manager']
    tags:
      - { name: event_subscriber }


This tells the event dispatcher the ContentTranslationUpdatesManager class subscribes to events.

When you look at \Drupal\content_translation\ContentTranslationUpdatesManager::getSubscribedEvents() you can see that it subscribes to the \Drupal\Core\Config\ConfigEvents::IMPORT event and when this event fires, the \Drupal\content_translation\ContentTranslationUpdatesManager::onConfigImporterImport() method should fire, with a priority of 60. Note that priority works in reverse to the typical Drupal weight: This listener goes before those with a lower priority and after those with a higher priority.

You can read about the generic event dispatcher in the symfony documentation.

The Drupal relevant bit here is the event_subscriber tag, which is processed in a compiler pass by \Drupal\Core\DependencyInjection\Compiler\RegisterEventSubscribersPass::process(), taking care of the registering of listeners automatically, based on the presence of that tag.