How to avoid calling performRequiredValidation() for custom element I'm trying to integrate Selectize plugin  within Drupal 8 Form API.
The important thing that I want to create 'optgroup' options.

I've used Selectize module and created a custom FieldWidget Field plugin.
Almost everything works, but I got some troubles with validation of my element.
Every time my form element submitted I receive an validation error: 


  "An illegal choice has been detected. Please contact the site
  administrator."


I've found the function, which sends me that error - performRequiredValidation().
I've found lines, so I can hack the core and add a case for my widget. But it's not a case for me.

if ($elements['#type'] == 'select') {
  $options = OptGroup::flattenOptions($elements['#options']);
}
else {
  $options = $elements['#options'];
}


So the only way I see - I have to avoid this validation somehow.
Plase help. Any suggestions would be appreciated.  

Here is a simplified code of my widget:

namespace Drupal\my_fields\Plugin\Field\FieldWidget;

use Drupal;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Field\Plugin\Field\FieldWidget\OptionsSelectWidget;

/**
 * Plugin implementation of the 'my_selectize_widget' widget.
 *
 * @FieldWidget(
 *   id = "my_selectize_widget",
 *   label = @Translation("My Selectize Widget"),
 *   module = "my_fields",
 *   field_types = {
 *     "entity_reference"
 *   },
 *   multiple_values = TRUE
 * )
 */
class MySelectizeWidget extends OptionsSelectWidget {

  /**
   * {@inheritdoc}
   */
  public function formElement(FieldItemListInterface $items, $delta, array $element, array &amp;$form, FormStateInterface $form_state) {
    $element = parent::formElement($items, $delta, $element, $form, $form_state);

    // Get our types.
    $grouped_types = _getTypesGrouped();

    // Override select form element.
    $element['#settings'] = [
      'plugins' =&gt; ['optgroup_columns'],
    ];
    $element['#type'] = 'selectize';
    $element['#options'] = $grouped_types;

    return $element;
  }

  /**
   * Get types grouped (options).
   */
  protected function _getTypesGrouped() {
    /**
     * // For example:
     * return [
     *   '1' =&gt; $this-&gt;t('One'),
     *   '2' =&gt; [
     *     '2.1' =&gt; $this-&gt;t('Two point one'),
     *     '2.2' =&gt; $this-&gt;t('Two point two'),
     *   ],
     *   '3' =&gt; $this-&gt;t('Three'),
     * ];
     */
  }

}
That error is caused from the following code.

  if (isset($elements['#options']) &amp;&amp; isset($elements['#value'])) {
    if ($elements['#type'] == 'select') {
      $options = OptGroup::flattenOptions($elements['#options']);
    }
    else {
      $options = $elements['#options'];
    }
    if (is_array($elements['#value'])) {
      $value = in_array($elements['#type'], array('checkboxes', 'tableselect')) ? array_keys($elements['#value']) : $elements['#value'];
      foreach ($value as $v) {
        if (!isset($options[$v])) {
          $form_state-&gt;setError($elements, $this-&gt;t('An illegal choice has been detected. Please contact the site administrator.'));
          $this-&gt;logger-&gt;error('Illegal choice %choice in %name element.', array('%choice' =&gt; $v, '%name' =&gt; empty($elements['#title']) ? $elements['#parents'][0] : $elements['#title']));
        }
      }
    }
    // Non-multiple select fields always have a value in HTML. If the user
    // does not change the form, it will be the value of the first option.
    // Because of this, form validation for the field will almost always
    // pass, even if the user did not select anything. To work around this
    // browser behavior, required select fields without a #default_value
    // get an additional, first empty option. In case the submitted value
    // is identical to the empty option's value, we reset the element's
    // value to NULL to trigger the regular #required handling below.
    // @see \Drupal\Core\Render\Element\Select::processSelect()
    elseif ($elements['#type'] == 'select' &amp;&amp; !$elements['#multiple'] &amp;&amp; $elements['#required'] &amp;&amp; !isset($elements['#default_value']) &amp;&amp; $elements['#value'] === $elements['#empty_value']) {
      $elements['#value'] = NULL;
      $form_state-&gt;setValueForElement($elements, NULL);
    }
    elseif (!isset($options[$elements['#value']])) {
      $form_state-&gt;setError($elements, $this-&gt;t('An illegal choice has been detected. Please contact the site administrator.'));
      $this-&gt;logger-&gt;error('Illegal choice %choice in %name element.', array('%choice' =&gt; $elements['#value'], '%name' =&gt; empty($elements['#title']) ? $elements['#parents'][0] : $elements['#title']));
    }
  }


It means that the value set for $elements['#value'] (which could also be a value submitted from the users) is not contained in $elements['#options']. In fact, your code contains the following code.

$grouped_types = _getTypesGrouped();

// Override select form element.
$element['#settings'] = [
  'plugins' =&gt; ['optgroup_columns'],
];
$element['#type'] = 'selectize';
$element['#options'] = $grouped_types;


Since there isn't a _getTypesGrouped() function, you are essentially setting $element['#options'] to NULL, which means you are removing all the possible values the form field for that widget can have.
The correct code you want to use is the following one.

$grouped_types = $this-&gt;_getTypesGrouped();

// Override select form element.
$element['#settings'] = [
  'plugins' =&gt; ['optgroup_columns'],
];
$element['#type'] = 'selectize';
$element['#options'] = $grouped_types;


As for avoiding Drupal runs FormValidator::performRequiredValidation(), that is a bad idea. The purpose of that method is avoiding users submit a forget form; removing it means to mine the site security.

As side note, protected method don't need an underscore at the beginning of their name, as per Drupal coding standards.