After adding info an entity via hook_ENTITY_TYPE_storage_load, how do I access that data in hook_ENTITY_TYPE_view? I'm adding data to the node on the storage_load hook, and trying to put it into the $build on the view hook. However, when I try to get the data, I can't figure out how to do it. $node->get('i18nfiles') gives me a "Field i18nfiles is unknown" exception, while $node->values['i18nfiles'] cannob be accessed because it is protected. Sure miss simple stdClass objects about now. :) Code below. 

/**
 * Implements hook_ENTITY_TYPE_storage_load() for nodes.
 *
 * @param type $nodes
 *   the array of nodes being loaded from the database.
 */
function hqq_node_storage_load(array $nodes) {
  $nids = array_keys($nodes);
  $result = db_query('SELECT fa.* FROM {node__field_attachments} fa INNER JOIN {node_field_data} nfd ON nfd.nid = fa.entity_id AND nfd.langcode = fa.langcode WHERE nfd.nid IN (:nids[]) AND nfd.status',[':nids[]' =&gt; $nids])-&gt;fetchAll();
  foreach ($result as $record) {
    $nodes[$record-&gt;entity_id]-&gt;i18nfiles['files'][$record-&gt;langcode] = $record-&gt;field_attachments_target_id;
  }
}

/**
 * Implements hook_ENTITY_TYPE_view() for nodes.
 *
 * @param array $build
 *   The renderable build array.
 * @param \Drupal\node\Entity\Node $entity
 *   The entity being rendered.
 * @param \Drupal\Core\Entity\Display\EntityViewDisplayInterface $display
 *   The entity view display holding the display options.
 * @param string $view_mode
 *   The view mode for the entity.
 *
 */
function hqq_node_view(array &amp;$build, \Drupal\node\Entity\Node $node, \Drupal\Core\Entity\Display\EntityViewDisplayInterface $display, string $view_mode) {
  if ($display-&gt;getComponent('i18nfiles') &amp;&amp; ($files = $node-&gt;get('i18nfiles')-&gt;getValue())) {
    foreach ($files as $langcode =&gt; $fid) {
      $lang = Drupal::languageManager()-&gt;getLanguage($langcode)-&gt;getName();
      $url = file_create_url(File::load($fid)-&gt;getFileUri());
      $options[$url] = $lang;
    }
    $build['i18nfiles'] = [
      '#type' =&gt; 'select',
      '#options' =&gt; $options,
      '#attributes' =&gt; ['class' =&gt; ['i18nfiles']],
    ];
  }
  if ($display-&gt;getComponent('i18noutdated') &amp;&amp; $node-&gt;get('content_translation_outdated')-&gt;value) {
    $build['i18noutdated'] = [
      '#type' =&gt; 'item',
      '#markup' =&gt; '&lt;div class="messages messages--warning"&gt;' . t('This translation is outdated') . '&lt;/div&gt;',
    ];
  }
}

/**
 * Implements hook_entity_field_info().
 * Returns an array of extra fields provided by the module.
 *
 * @return array
 *    The array of extra fields provided by hqq module.
 */
function hqq_entity_extra_field_info() {
  $extra = [];

  // Add the i18nfiles element, for translations of documents
  $extra['node']['document']['display']['i18nfiles'] = [
    'label' =&gt; t('Translated files'),
    'description' =&gt; t('A dropdown list of all languages in which a published translation is available'),
    'weight' =&gt; 10,
  ];

  foreach (NodeType::loadMultiple() as $bundle) {

    // Add also the 'language' select if Language module is enabled and the
    // bundle has multilingual support.
    // Visibility of the ordering of the language selector is the same as on the
    // node/add form.
    $configuration = ContentLanguageSettings::loadByEntityTypeBundle('node', $bundle-&gt;id());
    if ($configuration-&gt;getThirdPartySetting('content_translation', 'enabled')) {
      $extra['node'][$bundle-&gt;id()]['display']['i18ninprogress'] = [
        'label' =&gt; t('Translation in progress'),
        'description' =&gt; t('An indicator for if there are translations in progress.'),
        'weight' =&gt; 0,
      ];
      $extra['node'][$bundle-&gt;id()]['display']['i18noutdated'] = [
        'label' =&gt; t('Translation outdated'),
        'description' =&gt; t('A notification if the current translation is outdated.'),
        'weight' =&gt; 0,
      ];
    }
  }

  return $extra;
}
You access the property the same way you write it, as $node->i18nfiles. This goes through __set()/__get() which also supports non-fields.

That said, I'm a bit confused about what exactly you're doing. Your table name is node__field_attachments, so it looks like a managed field table, which would load the data automatically and making it available in $node->get('field_attachments')?

And since it's a field, you could then write a custom formatter for that field to display the data and get rid of those hooks.

It is also kind of a deprecated approach, if what I said is for some reason not possible, I'd recommend to either just load the data when you need it in hook_node_view() (with both node load being cached as well as rendered nodes being cached it's hard to compare what is more performant) or make it a computed field, but those are currently still quite painful to implement, see PathItem in Drupal 8.4.x.