/**
  * Gets the entity schema for the specified entity type.
  *
  * Entity types may override this method in order to optimize the generated
  * schema of the entity tables. However, only cross-field optimizations should
  * be added here; e.g., an index spanning multiple fields. Optimizations that
  * apply to a single field have to be added via
  * SqlContentEntityStorageSchema::getSharedTableFieldSchema() instead.
  *
  * @param \Drupal\Core\Entity\ContentEntityTypeInterface $entity_type
  *   The entity type definition.
  * @param bool $reset
  *   (optional) If set to TRUE static cache will be ignored and a new schema
  *   array generation will be performed. Defaults to FALSE.
  *
  * @return array
  *   A Schema API array describing the entity schema, excluding dedicated
  *   field tables.
  *
  * @throws \Drupal\Core\Field\FieldException
  */
 protected function getEntitySchema(ContentEntityTypeInterface $entity_type, $reset = FALSE)
 {
     $this->checkEntityType($entity_type);
     $entity_type_id = $entity_type->id();
     if (!isset($this->schema[$entity_type_id]) || $reset) {
         // Back up the storage definition and replace it with the passed one.
         // @todo Instead of switching the wrapped entity type, we should be able
         //   to instantiate a new table mapping for each entity type definition.
         //   See https://www.drupal.org/node/2274017.
         $actual_definition = $this->entityManager->getDefinition($entity_type_id);
         $this->storage->setEntityType($entity_type);
         // Prepare basic information about the entity type.
         $tables = $this->getEntitySchemaTables();
         // Initialize the table schema.
         $schema[$tables['base_table']] = $this->initializeBaseTable($entity_type);
         if (isset($tables['revision_table'])) {
             $schema[$tables['revision_table']] = $this->initializeRevisionTable($entity_type);
         }
         if (isset($tables['data_table'])) {
             $schema[$tables['data_table']] = $this->initializeDataTable($entity_type);
         }
         if (isset($tables['revision_data_table'])) {
             $schema[$tables['revision_data_table']] = $this->initializeRevisionDataTable($entity_type);
         }
         // We need to act only on shared entity schema tables.
         $table_mapping = $this->storage->getTableMapping();
         $table_names = array_diff($table_mapping->getTableNames(), $table_mapping->getDedicatedTableNames());
         $storage_definitions = $this->entityManager->getFieldStorageDefinitions($entity_type_id);
         foreach ($table_names as $table_name) {
             if (!isset($schema[$table_name])) {
                 $schema[$table_name] = array();
             }
             foreach ($table_mapping->getFieldNames($table_name) as $field_name) {
                 if (!isset($storage_definitions[$field_name])) {
                     throw new FieldException("Field storage definition for '{$field_name}' could not be found.");
                 } elseif ($table_mapping->allowsSharedTableStorage($storage_definitions[$field_name])) {
                     $column_names = $table_mapping->getColumnNames($field_name);
                     $storage_definition = $storage_definitions[$field_name];
                     $schema[$table_name] = array_merge_recursive($schema[$table_name], $this->getSharedTableFieldSchema($storage_definition, $table_name, $column_names));
                 }
             }
         }
         // Process tables after having gathered field information.
         $this->processBaseTable($entity_type, $schema[$tables['base_table']]);
         if (isset($tables['revision_table'])) {
             $this->processRevisionTable($entity_type, $schema[$tables['revision_table']]);
         }
         if (isset($tables['data_table'])) {
             $this->processDataTable($entity_type, $schema[$tables['data_table']]);
         }
         if (isset($tables['revision_data_table'])) {
             $this->processRevisionDataTable($entity_type, $schema[$tables['revision_data_table']]);
         }
         $this->schema[$entity_type_id] = $schema;
         // Restore the actual definition.
         $this->storage->setEntityType($actual_definition);
     }
     return $this->schema[$entity_type_id];
 }