From bbed679fbf96e68bb391e8b1e678a0caeff2e93f Mon Sep 17 00:00:00 2001
From: Alex Pott <alex.a.pott@googlemail.com>
Date: Wed, 8 Jan 2014 15:45:21 +0000
Subject: [PATCH] Issue #2144327 by amateescu, effulgentsia, yched, dasjo: Make
 all field types provide a schema().

---
 .../Core/Field/ConfigFieldItemInterface.php   | 36 ------------
 .../lib/Drupal/Core/Field/FieldDefinition.php | 58 +++++++++++++++++++
 .../Core/Field/FieldDefinitionInterface.php   | 32 ++++++++++
 .../Drupal/Core/Field/FieldItemInterface.php  | 35 +++++++++++
 .../Plugin/Field/FieldType/BooleanItem.php    | 16 +++++
 .../Field/Plugin/Field/FieldType/DateItem.php | 17 ++++++
 .../Plugin/Field/FieldType/EmailItem.php      | 34 +++++++++++
 .../Field/FieldType/EntityReferenceItem.php   | 38 ++++++++++++
 .../Plugin/Field/FieldType/FloatItem.php      | 16 +++++
 .../Plugin/Field/FieldType/IntegerItem.php    | 16 +++++
 .../Plugin/Field/FieldType/LanguageItem.php   | 16 +++++
 .../Field/FieldType/LegacyConfigFieldItem.php |  8 +--
 .../Field/Plugin/Field/FieldType/MapItem.php  | 16 +++++
 .../Plugin/Field/FieldType/StringItem.php     | 20 +++++++
 .../Field/Plugin/Field/FieldType/UriItem.php  | 15 +++++
 .../Plugin/Field/FieldType/CommentItem.php    |  4 +-
 .../Plugin/Field/FieldType/DateTimeItem.php   |  5 +-
 .../Drupal/email/ConfigurableEmailItem.php    | 48 +--------------
 .../ConfigurableEntityReferenceItem.php       | 42 ++++----------
 .../lib/Drupal/field/Entity/FieldInstance.php | 15 +++++
 .../field/lib/Drupal/field/FieldInterface.php | 29 ----------
 .../Plugin/Field/FieldType/ShapeItem.php      | 12 ++--
 .../Plugin/Field/FieldType/TestItem.php       |  4 +-
 .../file/Plugin/Field/FieldType/FileItem.php  |  4 +-
 .../Plugin/Field/FieldType/ImageItem.php      |  4 +-
 .../link/Plugin/Field/FieldType/LinkItem.php  |  4 +-
 .../Plugin/Field/FieldType/DecimalItem.php    |  8 +--
 .../Plugin/Field/FieldType/FloatItem.php      |  4 +-
 .../Plugin/Field/FieldType/IntegerItem.php    |  4 +-
 .../path/Plugin/Field/FieldType/PathItem.php  |  8 +++
 core/modules/system/system.module             | 15 ++++-
 .../FieldType/TaxonomyTermReferenceItem.php   |  4 +-
 .../Plugin/Field/FieldType/TelephoneItem.php  |  4 +-
 .../text/Plugin/Field/FieldType/TextItem.php  |  6 +-
 .../Plugin/Field/FieldType/TextLongItem.php   |  4 +-
 .../Field/FieldType/TextWithSummaryItem.php   |  4 +-
 .../lib/Drupal/user/Form/UserPasswordForm.php |  1 +
 .../Drupal/user/Tests/UserValidationTest.php  | 11 +++-
 core/modules/user/user.module                 |  5 --
 39 files changed, 427 insertions(+), 195 deletions(-)

diff --git a/core/lib/Drupal/Core/Field/ConfigFieldItemInterface.php b/core/lib/Drupal/Core/Field/ConfigFieldItemInterface.php
index 555070ad5017..980714d115ef 100644
--- a/core/lib/Drupal/Core/Field/ConfigFieldItemInterface.php
+++ b/core/lib/Drupal/Core/Field/ConfigFieldItemInterface.php
@@ -7,47 +7,11 @@
 
 namespace Drupal\Core\Field;
 
-use Drupal\field\FieldInterface;
-
 /**
  * Interface definition for 'configurable field type' plugins.
  */
 interface ConfigFieldItemInterface extends FieldItemInterface {
 
-  /**
-   * Returns the schema for the field.
-   *
-   * This method is static, because the field schema information is needed on
-   * creation of the field. No field instances exist by then, and it is not
-   * possible to instantiate a FieldItemInterface object yet.
-   *
-   * @param \Drupal\field\FieldInterface $field
-   *   The field definition.
-   *
-   * @return array
-   *   An associative array with the following key/value pairs:
-   *   - columns: An array of Schema API column specifications, keyed by column
-   *     name. This specifies what comprises a value for a given field. For
-   *     example, a value for a number field is simply 'value', while a value
-   *     for a formatted text field is the combination of 'value' and 'format'.
-   *     It is recommended to avoid having the column definitions depend on
-   *     field settings when possible. No assumptions should be made on how
-   *     storage engines internally use the original column name to structure
-   *     their storage.
-   *   - indexes: (optional) An array of Schema API index definitions. Only
-   *     columns that appear in the 'columns' array are allowed. Those indexes
-   *     will be used as default indexes. Callers of field_create_field() can
-   *     specify additional indexes or, at their own risk, modify the default
-   *     indexes specified by the field-type module. Some storage engines might
-   *     not support indexes.
-   *   - foreign keys: (optional) An array of Schema API foreign key
-   *     definitions. Note, however, that the field data is not necessarily
-   *     stored in SQL. Also, the possible usage is limited, as you cannot
-   *     specify another field as related, only existing SQL tables,
-   *     such as {taxonomy_term_data}.
-   */
-  public static function schema(FieldInterface $field);
-
   /**
    * Returns a form for the field-level settings.
    *
diff --git a/core/lib/Drupal/Core/Field/FieldDefinition.php b/core/lib/Drupal/Core/Field/FieldDefinition.php
index 882d086f4ad2..7df38b37ea61 100644
--- a/core/lib/Drupal/Core/Field/FieldDefinition.php
+++ b/core/lib/Drupal/Core/Field/FieldDefinition.php
@@ -10,12 +10,20 @@
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\TypedData\DataDefinition;
 use Drupal\Core\TypedData\ListDefinition;
+use Drupal\field\FieldException;
 
 /**
  * A class for defining entity fields.
  */
 class FieldDefinition extends ListDefinition implements FieldDefinitionInterface {
 
+  /**
+   * The field schema.
+   *
+   * @var array
+   */
+  protected $schema;
+
   /**
    * Creates a new field definition.
    *
@@ -201,4 +209,54 @@ public function getDefaultValue(EntityInterface $entity) {
     return $this->getSetting('default_value');
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function getSchema() {
+    if (!isset($this->schema)) {
+      // Get the schema from the field item class.
+      $definition = \Drupal::service('plugin.manager.field.field_type')->getDefinition($this->getFieldType());
+      $class = $definition['class'];
+      $schema = $class::schema($this);
+      // Fill in default values for optional entries.
+      $schema += array('indexes' => array(), 'foreign keys' => array());
+
+      // Check that the schema does not include forbidden column names.
+      if (array_intersect(array_keys($schema['columns']), static::getReservedColumns())) {
+        throw new FieldException('Illegal field type columns.');
+      }
+
+      // Merge custom indexes with those specified by the field type. Custom
+      // indexes prevail.
+      $schema['indexes'] = $this->indexes + $schema['indexes'];
+
+      $this->schema = $schema;
+    }
+
+    return $this->schema;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getColumns() {
+    $schema = $this->getSchema();
+    // A typical use case for the method is to iterate on the columns, while
+    // some other use cases rely on identifying the first column with the key()
+    // function. Since the schema is persisted in the Field object, we take care
+    // of resetting the array pointer so that the former does not interfere with
+    // the latter.
+    reset($schema['columns']);
+    return $schema['columns'];
+  }
+
+  /**
+   * A list of columns that can not be used as field type columns.
+   *
+   * @return array
+   */
+  public static function getReservedColumns() {
+    return array('deleted');
+  }
+
 }
diff --git a/core/lib/Drupal/Core/Field/FieldDefinitionInterface.php b/core/lib/Drupal/Core/Field/FieldDefinitionInterface.php
index 76f0ef90451f..123885ba2ecb 100644
--- a/core/lib/Drupal/Core/Field/FieldDefinitionInterface.php
+++ b/core/lib/Drupal/Core/Field/FieldDefinitionInterface.php
@@ -209,4 +209,36 @@ public function isMultiple();
    */
   public function getDefaultValue(EntityInterface $entity);
 
+  /**
+   * Returns the field schema.
+   *
+   * Note that this method returns an empty array for computed fields which have
+   * no schema.
+   *
+   * @return array
+   *   The field schema, as an array of key/value pairs in the format returned
+   *   by hook_field_schema():
+   *   - columns: An array of Schema API column specifications, keyed by column
+   *     name. This specifies what comprises a single value for a given field.
+   *     No assumptions should be made on how storage backends internally use
+   *     the original column name to structure their storage.
+   *   - indexes: An array of Schema API index definitions. Some storage
+   *     backends might not support indexes.
+   *   - foreign keys: An array of Schema API foreign key definitions. Note,
+   *     however, that depending on the storage backend specified for the field,
+   *     the field data is not necessarily stored in SQL.
+   */
+  public function getSchema();
+
+  /**
+   * Returns the field columns, as defined in the field schema.
+   *
+   * @return array
+   *   The array of field columns, keyed by column name, in the same format
+   *   returned by getSchema().
+   *
+   * @see \Drupal\field\Entity\FieldInterface::getSchema()
+   */
+  public function getColumns();
+
 }
diff --git a/core/lib/Drupal/Core/Field/FieldItemInterface.php b/core/lib/Drupal/Core/Field/FieldItemInterface.php
index 2cdd0c347a5b..bb1c5e5274b3 100644
--- a/core/lib/Drupal/Core/Field/FieldItemInterface.php
+++ b/core/lib/Drupal/Core/Field/FieldItemInterface.php
@@ -23,6 +23,41 @@
  */
 interface FieldItemInterface extends ComplexDataInterface {
 
+  /**
+   * Returns the schema for the field.
+   *
+   * This method is static because the field schema information is needed on
+   * creation of the field. FieldItemInterface objects instantiated at that
+   * time are not reliable as field instance settings might be missing.
+   *
+   * Computed fields having no schema should return an empty array.
+   *
+   * @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition
+   *   The field definition.
+   *
+   * @return array
+   *   An empty array if there is no schema, or an associative array with the
+   *   following key/value pairs:
+   *   - columns: An array of Schema API column specifications, keyed by column
+   *     name. The columns need to be a subset of the properties defined in
+   *     getPropertyDefinitions(). It is recommended to avoid having the column
+   *     definitions depend on field settings when possible. No assumptions
+   *     should be made on how storage engines internally use the original
+   *     column name to structure their storage.
+   *   - indexes: (optional) An array of Schema API index definitions. Only
+   *     columns that appear in the 'columns' array are allowed. Those indexes
+   *     will be used as default indexes. Callers of field_create_field() can
+   *     specify additional indexes or, at their own risk, modify the default
+   *     indexes specified by the field-type module. Some storage engines might
+   *     not support indexes.
+   *   - foreign keys: (optional) An array of Schema API foreign key
+   *     definitions. Note, however, that the field data is not necessarily
+   *     stored in SQL. Also, the possible usage is limited, as you cannot
+   *     specify another field as related, only existing SQL tables,
+   *     such as {taxonomy_term_data}.
+   */
+  public static function schema(FieldDefinitionInterface $field_definition);
+
   /**
    * Gets the entity that field belongs to.
    *
diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/BooleanItem.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/BooleanItem.php
index 994957c662bd..1d9884f96389 100644
--- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/BooleanItem.php
+++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/BooleanItem.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\Core\Field\Plugin\Field\FieldType;
 
+use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\Core\Field\FieldItemBase;
 use Drupal\Core\TypedData\DataDefinition;
 
@@ -42,4 +43,19 @@ public function getPropertyDefinitions() {
     return static::$propertyDefinitions;
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public static function schema(FieldDefinitionInterface $field_definition) {
+    return array(
+      'columns' => array(
+        'value' => array(
+          'type' => 'int',
+          'size' => 'tiny',
+          'not null' => TRUE,
+        ),
+      ),
+    );
+  }
+
 }
diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/DateItem.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/DateItem.php
index 59984c8c6d0a..c1276dd1022c 100644
--- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/DateItem.php
+++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/DateItem.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\Core\Field\Plugin\Field\FieldType;
 
+use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\Core\Field\FieldItemBase;
 
 /**
@@ -43,4 +44,20 @@ public function getPropertyDefinitions() {
     }
     return static::$propertyDefinitions;
   }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function schema(FieldDefinitionInterface $field_definition) {
+    return array(
+      'columns' => array(
+        'value' => array(
+          'type' => 'varchar',
+          'length' => 20,
+          'not null' => FALSE,
+        ),
+      ),
+    );
+  }
+
 }
diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EmailItem.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EmailItem.php
index 5a2c10712d02..9e687194e43d 100644
--- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EmailItem.php
+++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EmailItem.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\Core\Field\Plugin\Field\FieldType;
 
+use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\Core\Field\FieldItemBase;
 use Drupal\Core\TypedData\DataDefinition;
 
@@ -43,6 +44,39 @@ public function getPropertyDefinitions() {
     return static::$propertyDefinitions;
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public static function schema(FieldDefinitionInterface $field_definition) {
+    return array(
+      'columns' => array(
+        'value' => array(
+          'type' => 'varchar',
+          'length' => EMAIL_MAX_LENGTH,
+          'not null' => FALSE,
+        ),
+      ),
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getConstraints() {
+    $constraint_manager = \Drupal::typedDataManager()->getValidationConstraintManager();
+    $constraints = parent::getConstraints();
+
+    $constraints[] = $constraint_manager->create('ComplexData', array(
+      'value' => array(
+        'Length' => array(
+          'max' => EMAIL_MAX_LENGTH,
+          'maxMessage' => t('%name: the e-mail address can not be longer than @max characters.', array('%name' => $this->getFieldDefinition()->getLabel(), '@max' => EMAIL_MAX_LENGTH)),
+        )
+      ),
+    ));
+
+    return $constraints;
+  }
 
   /**
    * {@inheritdoc}
diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EntityReferenceItem.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EntityReferenceItem.php
index 40f7a3a7de6b..3a776e295db0 100644
--- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EntityReferenceItem.php
+++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EntityReferenceItem.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\Core\Field\Plugin\Field\FieldType;
 
+use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\Core\Field\FieldItemBase;
 use Drupal\Core\TypedData\DataDefinition;
 
@@ -82,6 +83,43 @@ public function getPropertyDefinitions() {
     return static::$propertyDefinitions[$key];
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public static function schema(FieldDefinitionInterface $field_definition) {
+    $target_type = $field_definition->getSetting('target_type');
+    $target_type_info = \Drupal::entityManager()->getDefinition($target_type);
+
+    if ($target_type_info->isSubclassOf('\Drupal\Core\Entity\ContentEntityInterface')) {
+      $columns = array(
+        'target_id' => array(
+          'description' => 'The ID of the target entity.',
+          'type' => 'int',
+          'unsigned' => TRUE,
+          'not null' => TRUE,
+        ),
+      );
+    }
+    else {
+      $columns = array(
+        'target_id' => array(
+          'description' => 'The ID of the target entity.',
+          'type' => 'varchar',
+          'length' => '255',
+        ),
+      );
+    }
+
+    $schema = array(
+      'columns' => $columns,
+      'indexes' => array(
+        'target_id' => array('target_id'),
+      ),
+    );
+
+    return $schema;
+  }
+
   /**
    * {@inheritdoc}
    */
diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/FloatItem.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/FloatItem.php
index e489a2f5cfef..045af1c92347 100644
--- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/FloatItem.php
+++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/FloatItem.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\Core\Field\Plugin\Field\FieldType;
 
+use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\Core\Field\FieldItemBase;
 use Drupal\Core\TypedData\DataDefinition;
 
@@ -42,4 +43,19 @@ public function getPropertyDefinitions() {
     }
     return static::$propertyDefinitions;
   }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function schema(FieldDefinitionInterface $field_definition) {
+    return array(
+      'columns' => array(
+        'value' => array(
+          'type' => 'float',
+          'not null' => FALSE,
+        ),
+      ),
+    );
+  }
+
 }
diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/IntegerItem.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/IntegerItem.php
index 82f088af6491..ec49cdb05181 100644
--- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/IntegerItem.php
+++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/IntegerItem.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\Core\Field\Plugin\Field\FieldType;
 
+use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\Core\Field\FieldItemBase;
 use Drupal\Core\TypedData\DataDefinition;
 
@@ -42,4 +43,19 @@ public function getPropertyDefinitions() {
     }
     return static::$propertyDefinitions;
   }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function schema(FieldDefinitionInterface $field_definition) {
+    return array(
+      'columns' => array(
+        'value' => array(
+          'type' => 'int',
+          'not null' => TRUE,
+        ),
+      ),
+    );
+  }
+
 }
diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/LanguageItem.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/LanguageItem.php
index bd4d8771a1ec..3bae65bfbb5f 100644
--- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/LanguageItem.php
+++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/LanguageItem.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\Core\Field\Plugin\Field\FieldType;
 
+use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\Core\Field\FieldItemBase;
 use Drupal\Core\Language\Language;
 use Drupal\Core\TypedData\DataDefinition;
@@ -55,6 +56,21 @@ public function getPropertyDefinitions() {
     return static::$propertyDefinitions;
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public static function schema(FieldDefinitionInterface $field_definition) {
+    return array(
+      'columns' => array(
+        'value' => array(
+          'type' => 'varchar',
+          'length' => 12,
+          'not null' => FALSE,
+        ),
+      ),
+    );
+  }
+
   /**
    * {@inheritdoc}
    */
diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/LegacyConfigFieldItem.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/LegacyConfigFieldItem.php
index 8c24ca9c6b71..b0f74fb64b01 100644
--- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/LegacyConfigFieldItem.php
+++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/LegacyConfigFieldItem.php
@@ -7,10 +7,10 @@
 
 namespace Drupal\Core\Field\Plugin\Field\FieldType;
 
+use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\Core\Field\PrepareCacheInterface;
 use Drupal\Core\Entity\EntityStorageControllerInterface;
 use Drupal\Core\Field\ConfigFieldItemBase;
-use Drupal\field\FieldInterface;
 use Drupal\field\FieldInstanceInterface;
 
 /**
@@ -31,13 +31,13 @@ abstract class LegacyConfigFieldItem extends ConfigFieldItemBase implements Prep
   /**
    * {@inheritdoc}
    */
-  public static function schema(FieldInterface $field) {
-    $definition = \Drupal::service('plugin.manager.field.field_type')->getDefinition($field->type);
+  public static function schema(FieldDefinitionInterface $field_definition) {
+    $definition = \Drupal::service('plugin.manager.field.field_type')->getDefinition($field_definition->type);
     $module = $definition['provider'];
     module_load_install($module);
     $callback = "{$module}_field_schema";
     if (function_exists($callback)) {
-      return $callback($field);
+      return $callback($field_definition);
     }
   }
 
diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/MapItem.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/MapItem.php
index 957b0e8d5fd6..698e5b8cba96 100644
--- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/MapItem.php
+++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/MapItem.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\Core\Field\Plugin\Field\FieldType;
 
+use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\Core\Field\FieldItemBase;
 
 /**
@@ -21,6 +22,21 @@
  */
 class MapItem extends FieldItemBase {
 
+  /**
+   * {@inheritdoc}
+   */
+  public static function schema(FieldDefinitionInterface $field_definition) {
+    return array(
+      'columns' => array(
+        'value' => array(
+          'type' => 'blob',
+          'size' => 'big',
+          'serialize' => TRUE,
+        ),
+      ),
+    );
+  }
+
   /**
    * {@inheritdoc}
    */
diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/StringItem.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/StringItem.php
index 9c63b3334c62..ce78a40c07b3 100644
--- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/StringItem.php
+++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/StringItem.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\Core\Field\Plugin\Field\FieldType;
 
+use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\Core\Field\FieldItemBase;
 use Drupal\Core\TypedData\DataDefinition;
 
@@ -17,6 +18,9 @@
  *   id = "string",
  *   label = @Translation("String"),
  *   description = @Translation("An entity field containing a string value."),
+ *   settings = {
+ *     "max_length" = "255"
+ *   },
  *   configurable = FALSE
  * )
  */
@@ -42,4 +46,20 @@ public function getPropertyDefinitions() {
     }
     return static::$propertyDefinitions;
   }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function schema(FieldDefinitionInterface $field_definition) {
+    return array(
+      'columns' => array(
+        'value' => array(
+          'type' => 'varchar',
+          'length' => $field_definition->getSetting('max_length'),
+          'not null' => FALSE,
+        ),
+      ),
+    );
+  }
+
 }
diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/UriItem.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/UriItem.php
index c1be2219decb..4cad163ff39f 100644
--- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/UriItem.php
+++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/UriItem.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\Core\Field\Plugin\Field\FieldType;
 
+use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\Core\Field\FieldItemBase;
 use Drupal\Core\TypedData\DataDefinition;
 
@@ -42,4 +43,18 @@ public function getPropertyDefinitions() {
     return self::$propertyDefinitions;
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public static function schema(FieldDefinitionInterface $field_definition) {
+    return array(
+      'columns' => array(
+        'value' => array(
+          'type' => 'text',
+          'not null' => TRUE,
+        ),
+      ),
+    );
+  }
+
 }
diff --git a/core/modules/comment/lib/Drupal/comment/Plugin/Field/FieldType/CommentItem.php b/core/modules/comment/lib/Drupal/comment/Plugin/Field/FieldType/CommentItem.php
index a68f8db58dc9..3145e8f626ed 100644
--- a/core/modules/comment/lib/Drupal/comment/Plugin/Field/FieldType/CommentItem.php
+++ b/core/modules/comment/lib/Drupal/comment/Plugin/Field/FieldType/CommentItem.php
@@ -8,7 +8,7 @@
 namespace Drupal\comment\Plugin\Field\FieldType;
 
 use Drupal\Core\TypedData\DataDefinition;
-use Drupal\field\FieldInterface;
+use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\Core\Field\ConfigFieldItemBase;
 
 /**
@@ -71,7 +71,7 @@ public function getPropertyDefinitions() {
   /**
    * {@inheritdoc}
    */
-  public static function schema(FieldInterface $field) {
+  public static function schema(FieldDefinitionInterface $field_definition) {
     return array(
       'columns' => array(
         'status' => array(
diff --git a/core/modules/datetime/lib/Drupal/datetime/Plugin/Field/FieldType/DateTimeItem.php b/core/modules/datetime/lib/Drupal/datetime/Plugin/Field/FieldType/DateTimeItem.php
index dc2c2015140f..c5a9cf72e9ac 100644
--- a/core/modules/datetime/lib/Drupal/datetime/Plugin/Field/FieldType/DateTimeItem.php
+++ b/core/modules/datetime/lib/Drupal/datetime/Plugin/Field/FieldType/DateTimeItem.php
@@ -7,10 +7,9 @@
 
 namespace Drupal\datetime\Plugin\Field\FieldType;
 
-use Drupal\Core\Datetime\DrupalDateTime;
+use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\Core\Field\PrepareCacheInterface;
 use Drupal\Core\TypedData\DataDefinition;
-use Drupal\field\FieldInterface;
 use Drupal\Core\Field\ConfigFieldItemBase;
 
 /**
@@ -69,7 +68,7 @@ public function getPropertyDefinitions() {
   /**
    * {@inheritdoc}
    */
-  public static function schema(FieldInterface $field) {
+  public static function schema(FieldDefinitionInterface $field_definition) {
     return array(
       'columns' => array(
         'value' => array(
diff --git a/core/modules/email/lib/Drupal/email/ConfigurableEmailItem.php b/core/modules/email/lib/Drupal/email/ConfigurableEmailItem.php
index 48e90ec769e6..65e08da0bb69 100644
--- a/core/modules/email/lib/Drupal/email/ConfigurableEmailItem.php
+++ b/core/modules/email/lib/Drupal/email/ConfigurableEmailItem.php
@@ -7,8 +7,8 @@
 
 namespace Drupal\email;
 
+use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\Core\Field\Plugin\Field\FieldType\EmailItem;
-use Drupal\field\FieldInterface;
 use Drupal\Core\Field\ConfigFieldItemInterface;
 
 /**
@@ -18,52 +18,6 @@
  */
 class ConfigurableEmailItem extends EmailItem implements ConfigFieldItemInterface {
 
-  /**
-   * Defines the max length for an email address
-   *
-   * The maximum length of an e-mail address is 254 characters. RFC 3696
-   * specifies a total length of 320 characters, but mentions that
-   * addresses longer than 256 characters are not normally useful. Erratum
-   * 1690 was then released which corrected this value to 254 characters.
-   * @see http://tools.ietf.org/html/rfc3696#section-3
-   * @see http://www.rfc-editor.org/errata_search.php?rfc=3696&eid=1690
-   */
-  const EMAIL_MAX_LENGTH = 254;
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function schema(FieldInterface $field) {
-    return array(
-      'columns' => array(
-        'value' => array(
-          'type' => 'varchar',
-          'length' => static::EMAIL_MAX_LENGTH,
-          'not null' => FALSE,
-        ),
-      ),
-    );
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getConstraints() {
-    $constraint_manager = \Drupal::typedDataManager()->getValidationConstraintManager();
-    $constraints = parent::getConstraints();
-
-    $constraints[] = $constraint_manager->create('ComplexData', array(
-      'value' => array(
-        'Length' => array(
-          'max' => static::EMAIL_MAX_LENGTH,
-          'maxMessage' => t('%name: the e-mail address can not be longer than @max characters.', array('%name' => $this->getFieldDefinition()->getLabel(), '@max' => static::EMAIL_MAX_LENGTH)),
-        )
-      ),
-    ));
-
-    return $constraints;
-  }
-
   /**
    * {@inheritdoc}
    */
diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/ConfigurableEntityReferenceItem.php b/core/modules/entity_reference/lib/Drupal/entity_reference/ConfigurableEntityReferenceItem.php
index 0f708c30a720..1a2a6181e1a9 100644
--- a/core/modules/entity_reference/lib/Drupal/entity_reference/ConfigurableEntityReferenceItem.php
+++ b/core/modules/entity_reference/lib/Drupal/entity_reference/ConfigurableEntityReferenceItem.php
@@ -8,7 +8,7 @@
 namespace Drupal\entity_reference;
 
 use Drupal\Core\TypedData\DataDefinition;
-use Drupal\field\FieldInterface;
+use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\Core\Field\ConfigEntityReferenceItemBase;
 use Drupal\Core\Field\ConfigFieldItemInterface;
 
@@ -66,43 +66,21 @@ public function getPropertyDefinitions() {
   /**
    * {@inheritdoc}
    */
-  public static function schema(FieldInterface $field) {
-    $target_type = $field->getSetting('target_type');
+  public static function schema(FieldDefinitionInterface $field_definition) {
+    $schema = parent::schema($field_definition);
+
+    $target_type = $field_definition->getSetting('target_type');
     $target_type_info = \Drupal::entityManager()->getDefinition($target_type);
 
     if ($target_type_info->isSubclassOf('\Drupal\Core\Entity\ContentEntityInterface')) {
-      $columns = array(
-        'target_id' => array(
-          'description' => 'The ID of the target entity.',
-          'type' => 'int',
-          'unsigned' => TRUE,
-          'not null' => TRUE,
-        ),
-        'revision_id' => array(
-          'description' => 'The revision ID of the target entity.',
-          'type' => 'int',
-          'unsigned' => TRUE,
-          'not null' => FALSE,
-        ),
-      );
-    }
-    else {
-      $columns = array(
-        'target_id' => array(
-          'description' => 'The ID of the target entity.',
-          'type' => 'varchar',
-          'length' => '255',
-        ),
+      $schema['columns']['revision_id'] = array(
+        'description' => 'The revision ID of the target entity.',
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'not null' => FALSE,
       );
     }
 
-    $schema = array(
-      'columns' => $columns,
-      'indexes' => array(
-        'target_id' => array('target_id'),
-      ),
-    );
-
     return $schema;
   }
 
diff --git a/core/modules/field/lib/Drupal/field/Entity/FieldInstance.php b/core/modules/field/lib/Drupal/field/Entity/FieldInstance.php
index 51eebbdb3184..1d9fdc48c86d 100644
--- a/core/modules/field/lib/Drupal/field/Entity/FieldInstance.php
+++ b/core/modules/field/lib/Drupal/field/Entity/FieldInstance.php
@@ -677,4 +677,19 @@ public function getItemDefinition() {
     }
     return $this->itemDefinition;
   }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getSchema() {
+    return $this->field->getSchema();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getColumns() {
+    return $this->field->getColumns();
+  }
+
 }
diff --git a/core/modules/field/lib/Drupal/field/FieldInterface.php b/core/modules/field/lib/Drupal/field/FieldInterface.php
index 78de421a8778..ed2658c8e7e0 100644
--- a/core/modules/field/lib/Drupal/field/FieldInterface.php
+++ b/core/modules/field/lib/Drupal/field/FieldInterface.php
@@ -15,35 +15,6 @@
  */
 interface FieldInterface extends ConfigEntityInterface, FieldDefinitionInterface {
 
-  /**
-   * Returns the field schema.
-   *
-   * @return array
-   *   The field schema, as an array of key/value pairs in the format returned
-   *   by hook_field_schema():
-   *   - columns: An array of Schema API column specifications, keyed by column
-   *     name. This specifies what comprises a single value for a given field.
-   *     No assumptions should be made on how storage backends internally use
-   *     the original column name to structure their storage.
-   *   - indexes: An array of Schema API index definitions. Some storage
-   *     backends might not support indexes.
-   *   - foreign keys: An array of Schema API foreign key definitions. Note,
-   *     however, that depending on the storage backend specified for the field,
-   *     the field data is not necessarily stored in SQL.
-   */
-  public function getSchema();
-
-  /**
-   * Returns the field columns, as defined in the field schema.
-   *
-   * @return array
-   *   The array of field columns, keyed by column name, in the same format
-   *   returned by getSchema().
-   *
-   * @see \Drupal\field\Entity\FieldInterface::getSchema()
-   */
-  public function getColumns();
-
   /**
    * Returns the list of bundles where the field has instances.
    *
diff --git a/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/Field/FieldType/ShapeItem.php b/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/Field/FieldType/ShapeItem.php
index fedd03c4544a..15d05cdeb94b 100644
--- a/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/Field/FieldType/ShapeItem.php
+++ b/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/Field/FieldType/ShapeItem.php
@@ -8,7 +8,7 @@
 namespace Drupal\field_test\Plugin\Field\FieldType;
 
 use Drupal\Core\TypedData\DataDefinition;
-use Drupal\field\FieldInterface;
+use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\Core\Field\ConfigFieldItemBase;
 
 /**
@@ -53,16 +53,16 @@ public function getPropertyDefinitions() {
   /**
    * {@inheritdoc}
    */
-  public static function schema(FieldInterface $field) {
+  public static function schema(FieldDefinitionInterface $field_definition) {
     $foreign_keys = array();
     // The 'foreign keys' key is not always used in tests.
-    if ($field->getSetting('foreign_key_name')) {
+    if ($field_definition->getSetting('foreign_key_name')) {
       $foreign_keys['foreign keys'] = array(
         // This is a dummy foreign key definition, references a table that
         // doesn't exist, but that's not a problem.
-        $field->getSetting('foreign_key_name') => array(
-          'table' => $field->getSetting('foreign_key_name'),
-          'columns' => array($field->getSetting('foreign_key_name') => 'id'),
+        $field_definition->getSetting('foreign_key_name') => array(
+          'table' => $field_definition->getSetting('foreign_key_name'),
+          'columns' => array($field_definition->getSetting('foreign_key_name') => 'id'),
         ),
       );
     }
diff --git a/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/Field/FieldType/TestItem.php b/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/Field/FieldType/TestItem.php
index ed8f38ab27fa..2157658e0a06 100644
--- a/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/Field/FieldType/TestItem.php
+++ b/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/Field/FieldType/TestItem.php
@@ -7,9 +7,9 @@
 
 namespace Drupal\field_test\Plugin\Field\FieldType;
 
+use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\Core\Field\PrepareCacheInterface;
 use Drupal\Core\TypedData\DataDefinition;
-use Drupal\field\FieldInterface;
 use Drupal\Core\Field\ConfigFieldItemBase;
 
 /**
@@ -57,7 +57,7 @@ public function getPropertyDefinitions() {
   /**
    * {@inheritdoc}
    */
-  public static function schema(FieldInterface $field) {
+  public static function schema(FieldDefinitionInterface $field_definition) {
     return array(
       'columns' => array(
         'value' => array(
diff --git a/core/modules/file/lib/Drupal/file/Plugin/Field/FieldType/FileItem.php b/core/modules/file/lib/Drupal/file/Plugin/Field/FieldType/FileItem.php
index 188ae853c671..9bb9dd0296e7 100644
--- a/core/modules/file/lib/Drupal/file/Plugin/Field/FieldType/FileItem.php
+++ b/core/modules/file/lib/Drupal/file/Plugin/Field/FieldType/FileItem.php
@@ -7,9 +7,9 @@
 
 namespace Drupal\file\Plugin\Field\FieldType;
 
+use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem;
 use Drupal\Core\TypedData\DataDefinition;
-use Drupal\field\FieldInterface;
 use Drupal\Core\Field\ConfigFieldItemInterface;
 
 /**
@@ -49,7 +49,7 @@ class FileItem extends EntityReferenceItem implements ConfigFieldItemInterface {
   /**
    * {@inheritdoc}
    */
-  public static function schema(FieldInterface $field) {
+  public static function schema(FieldDefinitionInterface $field_definition) {
     return array(
       'columns' => array(
         'target_id' => array(
diff --git a/core/modules/image/lib/Drupal/image/Plugin/Field/FieldType/ImageItem.php b/core/modules/image/lib/Drupal/image/Plugin/Field/FieldType/ImageItem.php
index 59e464c1bd02..be20c66536d3 100644
--- a/core/modules/image/lib/Drupal/image/Plugin/Field/FieldType/ImageItem.php
+++ b/core/modules/image/lib/Drupal/image/Plugin/Field/FieldType/ImageItem.php
@@ -8,7 +8,7 @@
 namespace Drupal\image\Plugin\Field\FieldType;
 
 use Drupal\Core\TypedData\DataDefinition;
-use Drupal\field\FieldInterface;
+use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\file\Plugin\Field\FieldType\FileItem;
 
 /**
@@ -70,7 +70,7 @@ class ImageItem extends FileItem {
   /**
    * {@inheritdoc}
    */
-  public static function schema(FieldInterface $field) {
+  public static function schema(FieldDefinitionInterface $field_definition) {
     return array(
       'columns' => array(
         'target_id' => array(
diff --git a/core/modules/link/lib/Drupal/link/Plugin/Field/FieldType/LinkItem.php b/core/modules/link/lib/Drupal/link/Plugin/Field/FieldType/LinkItem.php
index 3c914aea3f1a..eb9c2fc1f51d 100644
--- a/core/modules/link/lib/Drupal/link/Plugin/Field/FieldType/LinkItem.php
+++ b/core/modules/link/lib/Drupal/link/Plugin/Field/FieldType/LinkItem.php
@@ -9,7 +9,7 @@
 
 use Drupal\Core\Field\ConfigFieldItemBase;
 use Drupal\Core\TypedData\DataDefinition;
-use Drupal\field\FieldInterface;
+use Drupal\Core\Field\FieldDefinitionInterface;
 
 /**
  * Plugin implementation of the 'link' field type.
@@ -54,7 +54,7 @@ public function getPropertyDefinitions() {
   /**
    * {@inheritdoc}
    */
-  public static function schema(FieldInterface $field) {
+  public static function schema(FieldDefinitionInterface $field_definition) {
     return array(
       'columns' => array(
         'url' => array(
diff --git a/core/modules/number/lib/Drupal/number/Plugin/Field/FieldType/DecimalItem.php b/core/modules/number/lib/Drupal/number/Plugin/Field/FieldType/DecimalItem.php
index 51bb23b99505..3bf223e895f5 100644
--- a/core/modules/number/lib/Drupal/number/Plugin/Field/FieldType/DecimalItem.php
+++ b/core/modules/number/lib/Drupal/number/Plugin/Field/FieldType/DecimalItem.php
@@ -8,7 +8,7 @@
 namespace Drupal\number\Plugin\Field\FieldType;
 
 use Drupal\Core\TypedData\DataDefinition;
-use Drupal\field\FieldInterface;
+use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\Component\Utility\MapArray;
 
 /**
@@ -48,13 +48,13 @@ public function getPropertyDefinitions() {
   /**
    * {@inheritdoc}
    */
-  public static function schema(FieldInterface $field) {
+  public static function schema(FieldDefinitionInterface $field_definition) {
     return array(
       'columns' => array(
         'value' => array(
           'type' => 'numeric',
-          'precision' => $field->settings['precision'],
-          'scale' => $field->settings['scale'],
+          'precision' => $field_definition->settings['precision'],
+          'scale' => $field_definition->settings['scale'],
           'not null' => FALSE
         )
       ),
diff --git a/core/modules/number/lib/Drupal/number/Plugin/Field/FieldType/FloatItem.php b/core/modules/number/lib/Drupal/number/Plugin/Field/FieldType/FloatItem.php
index 88ee07f2352c..576514770fc4 100644
--- a/core/modules/number/lib/Drupal/number/Plugin/Field/FieldType/FloatItem.php
+++ b/core/modules/number/lib/Drupal/number/Plugin/Field/FieldType/FloatItem.php
@@ -8,7 +8,7 @@
 namespace Drupal\number\Plugin\Field\FieldType;
 
 use Drupal\Core\TypedData\DataDefinition;
-use Drupal\field\FieldInterface;
+use Drupal\Core\Field\FieldDefinitionInterface;
 
 /**
  * Plugin implementation of the 'number_float' field type.
@@ -43,7 +43,7 @@ public function getPropertyDefinitions() {
   /**
    * {@inheritdoc}
    */
-  public static function schema(FieldInterface $field) {
+  public static function schema(FieldDefinitionInterface $field_definition) {
     return array(
       'columns' => array(
         'value' => array(
diff --git a/core/modules/number/lib/Drupal/number/Plugin/Field/FieldType/IntegerItem.php b/core/modules/number/lib/Drupal/number/Plugin/Field/FieldType/IntegerItem.php
index dfe35f6a445d..6c44d7655da1 100644
--- a/core/modules/number/lib/Drupal/number/Plugin/Field/FieldType/IntegerItem.php
+++ b/core/modules/number/lib/Drupal/number/Plugin/Field/FieldType/IntegerItem.php
@@ -8,7 +8,7 @@
 namespace Drupal\number\Plugin\Field\FieldType;
 
 use Drupal\Core\TypedData\DataDefinition;
-use Drupal\field\FieldInterface;
+use Drupal\Core\Field\FieldDefinitionInterface;
 
 /**
  * Plugin implementation of the 'number_integer' field type.
@@ -43,7 +43,7 @@ public function getPropertyDefinitions() {
   /**
    * {@inheritdoc}
    */
-  public static function schema(FieldInterface $field) {
+  public static function schema(FieldDefinitionInterface $field_definition) {
     return array(
       'columns' => array(
         'value' => array(
diff --git a/core/modules/path/lib/Drupal/path/Plugin/Field/FieldType/PathItem.php b/core/modules/path/lib/Drupal/path/Plugin/Field/FieldType/PathItem.php
index 601bc0bfbcb5..6d75cac158de 100644
--- a/core/modules/path/lib/Drupal/path/Plugin/Field/FieldType/PathItem.php
+++ b/core/modules/path/lib/Drupal/path/Plugin/Field/FieldType/PathItem.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\path\Plugin\Field\FieldType;
 
+use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\Core\Field\FieldItemBase;
 use Drupal\Core\TypedData\DataDefinition;
 
@@ -45,4 +46,11 @@ public function getPropertyDefinitions() {
     return static::$propertyDefinitions;
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public static function schema(FieldDefinitionInterface $field_definition) {
+    return array();
+  }
+
 }
diff --git a/core/modules/system/system.module b/core/modules/system/system.module
index d5f46870fbbe..fc6f61cc5559 100644
--- a/core/modules/system/system.module
+++ b/core/modules/system/system.module
@@ -65,6 +65,18 @@
  */
 const REGIONS_ALL = 'all';
 
+/**
+ * Defines the max length for an email address
+ *
+ * The maximum length of an e-mail address is 254 characters. RFC 3696
+ * specifies a total length of 320 characters, but mentions that
+ * addresses longer than 256 characters are not normally useful. Erratum
+ * 1690 was then released which corrected this value to 254 characters.
+ * @see http://tools.ietf.org/html/rfc3696#section-3
+ * @see http://www.rfc-editor.org/errata_search.php?rfc=3696&eid=1690
+ */
+const EMAIL_MAX_LENGTH = 254;
+
 /**
  * Implements hook_help().
  */
@@ -337,8 +349,7 @@ function system_element_info() {
   $types['email'] = array(
     '#input' => TRUE,
     '#size' => 60,
-    // user.module is not loaded in case of early bootstrap errors.
-    '#maxlength' => defined('EMAIL_MAX_LENGTH') ? EMAIL_MAX_LENGTH : 255,
+    '#maxlength' => EMAIL_MAX_LENGTH,
     '#autocomplete_route_name' => FALSE,
     '#process' => array('form_process_autocomplete', 'ajax_process_form', 'form_process_pattern'),
     '#element_validate' => array('form_validate_email'),
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/Field/FieldType/TaxonomyTermReferenceItem.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/Field/FieldType/TaxonomyTermReferenceItem.php
index 13025de5517a..98660eb45e56 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/Field/FieldType/TaxonomyTermReferenceItem.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/Field/FieldType/TaxonomyTermReferenceItem.php
@@ -9,7 +9,7 @@
 
 use Drupal\Core\Field\ConfigEntityReferenceItemBase;
 use Drupal\Core\Field\ConfigFieldItemInterface;
-use Drupal\field\FieldInterface;
+use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\Core\Session\AccountInterface;
 use Drupal\Core\TypedData\AllowedValuesInterface;
 
@@ -97,7 +97,7 @@ public function getPropertyDefinitions() {
   /**
    * {@inheritdoc}
    */
-  public static function schema(FieldInterface $field) {
+  public static function schema(FieldDefinitionInterface $field_definition) {
     return array(
       'columns' => array(
         'target_id' => array(
diff --git a/core/modules/telephone/lib/Drupal/telephone/Plugin/Field/FieldType/TelephoneItem.php b/core/modules/telephone/lib/Drupal/telephone/Plugin/Field/FieldType/TelephoneItem.php
index e55fd523390c..67d7bdfd5f72 100644
--- a/core/modules/telephone/lib/Drupal/telephone/Plugin/Field/FieldType/TelephoneItem.php
+++ b/core/modules/telephone/lib/Drupal/telephone/Plugin/Field/FieldType/TelephoneItem.php
@@ -9,7 +9,7 @@
 
 use Drupal\Core\Field\ConfigFieldItemBase;
 use Drupal\Core\TypedData\DataDefinition;
-use Drupal\field\FieldInterface;
+use Drupal\Core\Field\FieldDefinitionInterface;
 
 /**
  * Plugin implementation of the 'telephone' field type.
@@ -34,7 +34,7 @@ class TelephoneItem extends ConfigFieldItemBase {
   /**
    * {@inheritdoc}
    */
-  public static function schema(FieldInterface $field) {
+  public static function schema(FieldDefinitionInterface $field_definition) {
     return array(
       'columns' => array(
         'value' => array(
diff --git a/core/modules/text/lib/Drupal/text/Plugin/Field/FieldType/TextItem.php b/core/modules/text/lib/Drupal/text/Plugin/Field/FieldType/TextItem.php
index ffa1edf7d11f..9157ee8c07e5 100644
--- a/core/modules/text/lib/Drupal/text/Plugin/Field/FieldType/TextItem.php
+++ b/core/modules/text/lib/Drupal/text/Plugin/Field/FieldType/TextItem.php
@@ -7,7 +7,7 @@
 
 namespace Drupal\text\Plugin\Field\FieldType;
 
-use Drupal\field\FieldInterface;
+use Drupal\Core\Field\FieldDefinitionInterface;
 
 /**
  * Plugin implementation of the 'text' field type.
@@ -31,12 +31,12 @@ class TextItem extends TextItemBase {
   /**
    * {@inheritdoc}
    */
-  public static function schema(FieldInterface $field) {
+  public static function schema(FieldDefinitionInterface $field_definition) {
     return array(
       'columns' => array(
         'value' => array(
           'type' => 'varchar',
-          'length' => $field->settings['max_length'],
+          'length' => $field_definition->getSetting('max_length'),
           'not null' => FALSE,
         ),
         'format' => array(
diff --git a/core/modules/text/lib/Drupal/text/Plugin/Field/FieldType/TextLongItem.php b/core/modules/text/lib/Drupal/text/Plugin/Field/FieldType/TextLongItem.php
index 9911a93dab42..7e378fc6481c 100644
--- a/core/modules/text/lib/Drupal/text/Plugin/Field/FieldType/TextLongItem.php
+++ b/core/modules/text/lib/Drupal/text/Plugin/Field/FieldType/TextLongItem.php
@@ -7,7 +7,7 @@
 
 namespace Drupal\text\Plugin\Field\FieldType;
 
-use Drupal\field\FieldInterface;
+use Drupal\Core\Field\FieldDefinitionInterface;
 
 /**
  * Plugin implementation of the 'text_long' field type.
@@ -28,7 +28,7 @@ class TextLongItem extends TextItemBase {
   /**
    * {@inheritdoc}
    */
-  public static function schema(FieldInterface $field) {
+  public static function schema(FieldDefinitionInterface $field_definition) {
     return array(
       'columns' => array(
         'value' => array(
diff --git a/core/modules/text/lib/Drupal/text/Plugin/Field/FieldType/TextWithSummaryItem.php b/core/modules/text/lib/Drupal/text/Plugin/Field/FieldType/TextWithSummaryItem.php
index 1efad43f3066..36df9508c174 100644
--- a/core/modules/text/lib/Drupal/text/Plugin/Field/FieldType/TextWithSummaryItem.php
+++ b/core/modules/text/lib/Drupal/text/Plugin/Field/FieldType/TextWithSummaryItem.php
@@ -8,7 +8,7 @@
 namespace Drupal\text\Plugin\Field\FieldType;
 
 use Drupal\Core\TypedData\DataDefinition;
-use Drupal\field\FieldInterface;
+use Drupal\Core\Field\FieldDefinitionInterface;
 
 /**
  * Plugin implementation of the 'text_with_summary' field type.
@@ -57,7 +57,7 @@ public function getPropertyDefinitions() {
   /**
    * {@inheritdoc}
    */
-  public static function schema(FieldInterface $field) {
+  public static function schema(FieldDefinitionInterface $field_definition) {
     return array(
       'columns' => array(
         'value' => array(
diff --git a/core/modules/user/lib/Drupal/user/Form/UserPasswordForm.php b/core/modules/user/lib/Drupal/user/Form/UserPasswordForm.php
index 07d35e995398..236b293eb028 100644
--- a/core/modules/user/lib/Drupal/user/Form/UserPasswordForm.php
+++ b/core/modules/user/lib/Drupal/user/Form/UserPasswordForm.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\user\Form;
 
+use Drupal\Core\Field\Plugin\Field\FieldType\EmailItem;
 use Drupal\Core\Form\FormBase;
 use Drupal\Core\Language\Language;
 use Drupal\Core\Language\LanguageManager;
diff --git a/core/modules/user/lib/Drupal/user/Tests/UserValidationTest.php b/core/modules/user/lib/Drupal/user/Tests/UserValidationTest.php
index cf68623ee774..8b54b67881a9 100644
--- a/core/modules/user/lib/Drupal/user/Tests/UserValidationTest.php
+++ b/core/modules/user/lib/Drupal/user/Tests/UserValidationTest.php
@@ -8,6 +8,7 @@
 namespace Drupal\user\Tests;
 
 use Drupal\Core\Entity\EntityInterface;
+use Drupal\Core\Field\Plugin\Field\FieldType\EmailItem;
 use Drupal\simpletest\DrupalUnitTestBase;
 
 /**
@@ -109,9 +110,15 @@ function testValidation() {
     $mail = $this->randomName(EMAIL_MAX_LENGTH - 11) . '@example.com';
     $user->set('mail', $mail);
     $violations = $user->validate();
-    $this->assertEqual(count($violations), 1, 'Violation found when email is too long');
+    // @todo There are two violations because EmailItem::getConstraints()
+    //   overlaps with the implicit constraint of the 'email' property type used
+    //   in EmailItem::getPropertyDefinitions(). Resolve this in
+    //   https://drupal.org/node/2023465.
+    $this->assertEqual(count($violations), 2, 'Violations found when email is too long');
     $this->assertEqual($violations[0]->getPropertyPath(), 'mail.0.value');
-    $this->assertEqual($violations[0]->getMessage(), t('This value is not a valid email address.'));
+    $this->assertEqual($violations[0]->getMessage(), t('%name: the e-mail address can not be longer than @max characters.', array('%name' => $user->get('mail')->getFieldDefinition()->getLabel(), '@max' => EMAIL_MAX_LENGTH)));
+    $this->assertEqual($violations[1]->getPropertyPath(), 'mail.0.value');
+    $this->assertEqual($violations[1]->getMessage(), t('This value is not a valid email address.'));
 
     // Provoke a e-mail collision with an exsiting user.
     $user->set('mail', 'existing@example.com');
diff --git a/core/modules/user/user.module b/core/modules/user/user.module
index f6a30cbde5da..1e710a975233 100644
--- a/core/modules/user/user.module
+++ b/core/modules/user/user.module
@@ -24,11 +24,6 @@
  */
 const USERNAME_MAX_LENGTH = 60;
 
-/**
- * Maximum length of user e-mail text field.
- */
-const EMAIL_MAX_LENGTH = 255;
-
 /**
  * Only administrators can create user accounts.
  */
-- 
GitLab