/**
 * Copyright (c) 2011, 2015 - Lunifera GmbH (Gross Enzersdorf, Austria), Loetz GmbH&Co.KG (69115 Heidelberg, Germany)
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 * 
 * SPDX-License-Identifier: EPL-2.0
 * 
 * Contributors:
 *         Florian Pirchner - Initial implementation
 */
package org.eclipse.osbp.dsl.common.xtext.jvmmodel;

import com.google.common.base.Objects;
import com.google.inject.Inject;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.ListIterator;
import java.util.function.Consumer;
import javax.validation.Valid;
import javax.validation.constraints.AssertFalse;
import javax.validation.constraints.AssertTrue;
import javax.validation.constraints.DecimalMax;
import javax.validation.constraints.DecimalMin;
import javax.validation.constraints.Digits;
import javax.validation.constraints.Future;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Null;
import javax.validation.constraints.Past;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.osbp.dsl.common.xtext.extensions.AnnotationExtension;
import org.eclipse.osbp.dsl.semantic.common.types.LAnnotationDef;
import org.eclipse.osbp.dsl.semantic.common.types.LAnnotationTarget;
import org.eclipse.osbp.dsl.semantic.common.types.LAttribute;
import org.eclipse.osbp.dsl.semantic.common.types.LConstraintSeverity;
import org.eclipse.osbp.dsl.semantic.common.types.LDataType;
import org.eclipse.osbp.dsl.semantic.common.types.LDatatypeConstraint;
import org.eclipse.osbp.dsl.semantic.common.types.LDtCAssertFalse;
import org.eclipse.osbp.dsl.semantic.common.types.LDtCAssertTrue;
import org.eclipse.osbp.dsl.semantic.common.types.LDtCDecimalMax;
import org.eclipse.osbp.dsl.semantic.common.types.LDtCDecimalMin;
import org.eclipse.osbp.dsl.semantic.common.types.LDtCDigits;
import org.eclipse.osbp.dsl.semantic.common.types.LDtCFuture;
import org.eclipse.osbp.dsl.semantic.common.types.LDtCNotNull;
import org.eclipse.osbp.dsl.semantic.common.types.LDtCNull;
import org.eclipse.osbp.dsl.semantic.common.types.LDtCNumericMax;
import org.eclipse.osbp.dsl.semantic.common.types.LDtCNumericMin;
import org.eclipse.osbp.dsl.semantic.common.types.LDtCPast;
import org.eclipse.osbp.dsl.semantic.common.types.LDtCRegEx;
import org.eclipse.osbp.dsl.semantic.common.types.LDtCSize;
import org.eclipse.osbp.dsl.semantic.common.types.LKeyAndValue;
import org.eclipse.osbp.dsl.semantic.common.types.LOperation;
import org.eclipse.osbp.dsl.semantic.common.types.LReference;
import org.eclipse.osbp.dsl.semantic.common.types.LScalarType;
import org.eclipse.osbp.dsl.semantic.common.types.LType;
import org.eclipse.osbp.runtime.common.annotations.BeanOnTab;
import org.eclipse.osbp.runtime.common.annotations.Dirty;
import org.eclipse.osbp.runtime.common.annotations.Properties;
import org.eclipse.osbp.runtime.common.annotations.Property;
import org.eclipse.osbp.runtime.common.validation.ErrorSeverity;
import org.eclipse.osbp.runtime.common.validation.InfoSeverity;
import org.eclipse.osbp.runtime.common.validation.WarningSeverity;
import org.eclipse.xtext.common.types.JvmAnnotationReference;
import org.eclipse.xtext.common.types.JvmAnnotationValue;
import org.eclipse.xtext.common.types.JvmField;
import org.eclipse.xtext.common.types.JvmGenericType;
import org.eclipse.xtext.common.types.JvmMember;
import org.eclipse.xtext.common.types.JvmOperation;
import org.eclipse.xtext.common.types.JvmTypeReference;
import org.eclipse.xtext.common.types.util.TypeReferences;
import org.eclipse.xtext.xbase.annotations.xAnnotations.XAnnotation;
import org.eclipse.xtext.xbase.jvmmodel.JvmTypesBuilder;
import org.eclipse.xtext.xbase.lib.CollectionLiterals;
import org.eclipse.xtext.xbase.lib.Conversions;
import org.eclipse.xtext.xbase.lib.Extension;
import org.eclipse.xtext.xbase.lib.Functions.Function1;
import org.eclipse.xtext.xbase.lib.IterableExtensions;
import org.eclipse.xtext.xbase.lib.StringExtensions;

/**
 * This class is responsible to generate the Annotations defined in the entity model
 */
@SuppressWarnings("all")
public class AnnotationCompiler {
  @Inject
  @Extension
  private JvmTypesBuilder _jvmTypesBuilder;
  
  @Inject
  @Extension
  private AnnotationExtension _annotationExtension;
  
  @Inject
  @Extension
  private TypeReferences _typeReferences;
  
  public void processAnnotation(final LAnnotationTarget annotationTarget, final JvmMember jvmMember) {
    this.internalProcessAnnotation(annotationTarget, jvmMember);
  }
  
  protected void _internalProcessAnnotation(final LType bean, final JvmGenericType jvmType) {
    final Function1<LAnnotationDef, Boolean> _function = (LAnnotationDef it) -> {
      boolean _isExclude = it.isExclude();
      return Boolean.valueOf((!_isExclude));
    };
    final Function1<LAnnotationDef, XAnnotation> _function_1 = (LAnnotationDef it) -> {
      return it.getAnnotation();
    };
    this._jvmTypesBuilder.translateAnnotationsTo(IterableExtensions.<LAnnotationDef, XAnnotation>map(IterableExtensions.<LAnnotationDef>filter(bean.getResolvedAnnotations(), _function), _function_1), jvmType);
  }
  
  protected void _internalProcessAnnotation(final LReference ref, final JvmField jvmType) {
    final Function1<LAnnotationDef, Boolean> _function = (LAnnotationDef it) -> {
      boolean _isExclude = it.isExclude();
      return Boolean.valueOf((!_isExclude));
    };
    final Function1<LAnnotationDef, XAnnotation> _function_1 = (LAnnotationDef it) -> {
      return it.getAnnotation();
    };
    this._jvmTypesBuilder.translateAnnotationsTo(IterableExtensions.<LAnnotationDef, XAnnotation>map(IterableExtensions.<LAnnotationDef>filter(ref.getResolvedAnnotations(), _function), _function_1), jvmType);
  }
  
  protected void _internalProcessAnnotation(final LAttribute att, final JvmField jvmType) {
    final Function1<LAnnotationDef, Boolean> _function = (LAnnotationDef it) -> {
      boolean _isExclude = it.isExclude();
      return Boolean.valueOf((!_isExclude));
    };
    final Function1<LAnnotationDef, XAnnotation> _function_1 = (LAnnotationDef it) -> {
      return it.getAnnotation();
    };
    this._jvmTypesBuilder.translateAnnotationsTo(IterableExtensions.<LAnnotationDef, XAnnotation>map(IterableExtensions.<LAnnotationDef>filter(att.getResolvedAnnotations(), _function), _function_1), jvmType);
  }
  
  public void toDatatypeBasedConstraintAnnotations(final LAttribute att, final JvmField jvmType) {
    LScalarType _type = att.getType();
    if ((_type instanceof LDataType)) {
      LScalarType _type_1 = att.getType();
      final LDataType dt = ((LDataType) _type_1);
      EList<LDatatypeConstraint> _constraints = dt.getConstraints();
      for (final LDatatypeConstraint c : _constraints) {
        this.toConstraintAnnotation(c, jvmType);
      }
    }
  }
  
  protected List<LKeyAndValue> mergeKeyAndValues(final LAttribute att) {
    final ArrayList<LKeyAndValue> keyAndValues = CollectionLiterals.<LKeyAndValue>newArrayList();
    this.addDatatypeKeyAndValues(att, keyAndValues);
    keyAndValues.addAll(att.getProperties());
    this.removeDuplicateKeys(keyAndValues);
    return keyAndValues;
  }
  
  protected List<LKeyAndValue> mergeKeyAndValues(final LReference ref) {
    final ArrayList<LKeyAndValue> keyAndValues = CollectionLiterals.<LKeyAndValue>newArrayList();
    keyAndValues.addAll(ref.getProperties());
    this.removeDuplicateKeys(keyAndValues);
    return keyAndValues;
  }
  
  protected void removeDuplicateKeys(final List<LKeyAndValue> result) {
    int _size = result.size();
    boolean _equals = (_size == 0);
    if (_equals) {
      return;
    }
    final ArrayList<String> keys = CollectionLiterals.<String>newArrayList();
    int _size_1 = result.size();
    int _minus = (_size_1 - 1);
    final ListIterator<LKeyAndValue> iter = result.listIterator(_minus);
    while (iter.hasPrevious()) {
      {
        final LKeyAndValue temp = iter.previous();
        boolean _contains = keys.contains(temp.getKey());
        if (_contains) {
          iter.remove();
        } else {
          String _key = temp.getKey();
          keys.add(_key);
        }
      }
    }
  }
  
  protected boolean addDatatypeKeyAndValues(final LAttribute att, final List<LKeyAndValue> result) {
    boolean _xifexpression = false;
    LScalarType _type = att.getType();
    if ((_type instanceof LDataType)) {
      boolean _xblockexpression = false;
      {
        LScalarType _type_1 = att.getType();
        final LDataType dt = ((LDataType) _type_1);
        _xblockexpression = result.addAll(dt.getProperties());
      }
      _xifexpression = _xblockexpression;
    }
    return _xifexpression;
  }
  
  protected void toPropertiesAnnotation(final EObject context, final List<LKeyAndValue> keyValues, final JvmField field) {
    if ((Objects.equal(keyValues, null) || (keyValues.size() == 0))) {
      return;
    }
    final ArrayList<JvmAnnotationReference> innerAnnotations = CollectionLiterals.<JvmAnnotationReference>newArrayList();
    final Consumer<LKeyAndValue> _function = (LKeyAndValue it) -> {
      final JvmAnnotationReference innerAnno = this._jvmTypesBuilder.toAnnotation(context, Property.class);
      this._annotationExtension.addAnnAttr(innerAnno, it, "key", it.getKey());
      this._annotationExtension.addAnnAttr(innerAnno, it, "value", it.getValue());
      innerAnnotations.add(innerAnno);
    };
    keyValues.forEach(_function);
    final JvmAnnotationReference mainAnno = this._jvmTypesBuilder.toAnnotation(context, Properties.class);
    this._annotationExtension.addAnnAttr(mainAnno, context, "properties", 
      innerAnnotations.<JvmAnnotationReference>toArray(new JvmAnnotationReference[((Object[])Conversions.unwrapArray(innerAnnotations, Object.class)).length]));
    EList<JvmAnnotationReference> _annotations = field.getAnnotations();
    this._jvmTypesBuilder.<JvmAnnotationReference>operator_add(_annotations, mainAnno);
  }
  
  /**
   * Annotation to tell validator, that nested properties should be validated too
   */
  protected void toValidAnnotation(final EObject context, final JvmField field) {
    final JvmAnnotationReference anno = this._jvmTypesBuilder.toAnnotation(context, Valid.class);
    EList<JvmAnnotationReference> _annotations = field.getAnnotations();
    this._jvmTypesBuilder.<JvmAnnotationReference>operator_add(_annotations, anno);
  }
  
  protected void toBeanOnTabAnnotation(final EObject context, final JvmField field) {
    final JvmAnnotationReference anno = this._jvmTypesBuilder.toAnnotation(context, BeanOnTab.class);
    EList<JvmAnnotationReference> _annotations = field.getAnnotations();
    this._jvmTypesBuilder.<JvmAnnotationReference>operator_add(_annotations, anno);
  }
  
  /**
   * Annotation for the dirty state
   */
  public void toDirtyAnnotation(final EObject context, final JvmField field) {
    final JvmAnnotationReference anno = this._jvmTypesBuilder.toAnnotation(context, Dirty.class);
    EList<JvmAnnotationReference> _annotations = field.getAnnotations();
    this._jvmTypesBuilder.<JvmAnnotationReference>operator_add(_annotations, anno);
  }
  
  protected boolean _isValidAllowed(final Void voidx) {
    return false;
  }
  
  protected boolean _isValidAllowed(final LDataType type) {
    boolean _isAsPrimitive = type.isAsPrimitive();
    if (_isAsPrimitive) {
      return false;
    }
    JvmTypeReference _jvmTypeReference = type.getJvmTypeReference();
    String _qualifiedName = null;
    if (_jvmTypeReference!=null) {
      _qualifiedName=_jvmTypeReference.getQualifiedName();
    }
    boolean _isPrimitiveJvmType = this.isPrimitiveJvmType(_qualifiedName);
    if (_isPrimitiveJvmType) {
      return false;
    }
    return true;
  }
  
  protected boolean _isValidAllowed(final LScalarType type) {
    return false;
  }
  
  public boolean isPrimitiveJvmType(final String value) {
    boolean _equals = Objects.equal(value, null);
    if (_equals) {
      return false;
    }
    boolean _matched = false;
    String _name = Integer.class.getName();
    if (Objects.equal(value, _name)) {
      _matched=true;
      return true;
    }
    if (!_matched) {
      String _name_1 = Integer.TYPE.getName();
      if (Objects.equal(value, _name_1)) {
        _matched=true;
        return true;
      }
    }
    if (!_matched) {
      String _name_2 = Boolean.class.getName();
      if (Objects.equal(value, _name_2)) {
        _matched=true;
        return true;
      }
    }
    if (!_matched) {
      String _name_3 = Boolean.TYPE.getName();
      if (Objects.equal(value, _name_3)) {
        _matched=true;
        return true;
      }
    }
    if (!_matched) {
      String _name_4 = Short.class.getName();
      if (Objects.equal(value, _name_4)) {
        _matched=true;
        return true;
      }
    }
    if (!_matched) {
      String _name_5 = Short.TYPE.getName();
      if (Objects.equal(value, _name_5)) {
        _matched=true;
        return true;
      }
    }
    if (!_matched) {
      String _name_6 = Long.class.getName();
      if (Objects.equal(value, _name_6)) {
        _matched=true;
        return true;
      }
    }
    if (!_matched) {
      String _name_7 = Long.TYPE.getName();
      if (Objects.equal(value, _name_7)) {
        _matched=true;
        return true;
      }
    }
    if (!_matched) {
      String _name_8 = Double.class.getName();
      if (Objects.equal(value, _name_8)) {
        _matched=true;
        return true;
      }
    }
    if (!_matched) {
      String _name_9 = Double.TYPE.getName();
      if (Objects.equal(value, _name_9)) {
        _matched=true;
        return true;
      }
    }
    if (!_matched) {
      String _name_10 = Float.class.getName();
      if (Objects.equal(value, _name_10)) {
        _matched=true;
        return true;
      }
    }
    if (!_matched) {
      String _name_11 = Float.TYPE.getName();
      if (Objects.equal(value, _name_11)) {
        _matched=true;
        return true;
      }
    }
    if (!_matched) {
      String _name_12 = Character.class.getName();
      if (Objects.equal(value, _name_12)) {
        _matched=true;
        return true;
      }
    }
    if (!_matched) {
      String _name_13 = Character.TYPE.getName();
      if (Objects.equal(value, _name_13)) {
        _matched=true;
        return true;
      }
    }
    if (!_matched) {
      String _name_14 = Byte.class.getName();
      if (Objects.equal(value, _name_14)) {
        _matched=true;
        return true;
      }
    }
    if (!_matched) {
      String _name_15 = Byte.TYPE.getName();
      if (Objects.equal(value, _name_15)) {
        _matched=true;
        return true;
      }
    }
    if (!_matched) {
      String _name_16 = Boolean.class.getName();
      if (Objects.equal(value, _name_16)) {
        _matched=true;
        return true;
      }
    }
    if (!_matched) {
      String _name_17 = Boolean.TYPE.getName();
      if (Objects.equal(value, _name_17)) {
        _matched=true;
        return true;
      }
    }
    if (!_matched) {
      String _name_18 = String.class.getName();
      if (Objects.equal(value, _name_18)) {
        _matched=true;
        return true;
      }
    }
    return false;
  }
  
  protected void _toConstraintAnnotation(final LDtCAssertFalse constraint, final JvmField field) {
    final JvmAnnotationReference anno = this._jvmTypesBuilder.toAnnotation(constraint, AssertFalse.class);
    this.handlePayloadAndMessages(constraint, anno);
    EList<JvmAnnotationReference> _annotations = field.getAnnotations();
    this._jvmTypesBuilder.<JvmAnnotationReference>operator_add(_annotations, anno);
  }
  
  protected JvmAnnotationValue handlePayloadAndMessages(final LDatatypeConstraint constraint, final JvmAnnotationReference anno) {
    JvmAnnotationValue _xblockexpression = null;
    {
      LConstraintSeverity _severity = constraint.getSeverity();
      if (_severity != null) {
        switch (_severity) {
          case INFO:
            this._annotationExtension.addAnnAttr(anno, constraint, "payload", this._typeReferences.getTypeForName(InfoSeverity.class, constraint));
            break;
          case WARNING:
            this._annotationExtension.addAnnAttr(anno, constraint, "payload", this._typeReferences.getTypeForName(WarningSeverity.class, constraint));
            break;
          case ERROR:
            this._annotationExtension.addAnnAttr(anno, constraint, "payload", this._typeReferences.getTypeForName(ErrorSeverity.class, constraint));
            break;
          default:
            break;
        }
      }
      final StringBuilder b = new StringBuilder();
      boolean _isNullOrEmpty = StringExtensions.isNullOrEmpty(constraint.getMsgI18nKey());
      boolean _not = (!_isNullOrEmpty);
      if (_not) {
        b.append(constraint.getMsgI18nKey());
      }
      boolean _isNullOrEmpty_1 = StringExtensions.isNullOrEmpty(constraint.getMsgCode());
      boolean _not_1 = (!_isNullOrEmpty_1);
      if (_not_1) {
        b.append(":");
        b.append(constraint.getMsgCode());
      }
      JvmAnnotationValue _xifexpression = null;
      boolean _isNullOrEmpty_2 = StringExtensions.isNullOrEmpty(b.toString());
      boolean _not_2 = (!_isNullOrEmpty_2);
      if (_not_2) {
        String _string = b.toString();
        String _plus = ("{" + _string);
        String _plus_1 = (_plus + "}");
        _xifexpression = this._annotationExtension.addAnnAttr(anno, constraint, "message", _plus_1);
      }
      _xblockexpression = _xifexpression;
    }
    return _xblockexpression;
  }
  
  protected void _toConstraintAnnotation(final LDtCAssertTrue constraint, final JvmField field) {
    final JvmAnnotationReference anno = this._jvmTypesBuilder.toAnnotation(constraint, AssertTrue.class);
    this.handlePayloadAndMessages(constraint, anno);
    EList<JvmAnnotationReference> _annotations = field.getAnnotations();
    this._jvmTypesBuilder.<JvmAnnotationReference>operator_add(_annotations, anno);
  }
  
  protected void _toConstraintAnnotation(final LDtCNotNull constraint, final JvmField field) {
    final JvmAnnotationReference anno = this._jvmTypesBuilder.toAnnotation(constraint, NotNull.class);
    this.handlePayloadAndMessages(constraint, anno);
    EList<JvmAnnotationReference> _annotations = field.getAnnotations();
    this._jvmTypesBuilder.<JvmAnnotationReference>operator_add(_annotations, anno);
  }
  
  protected void _toConstraintAnnotation(final LDtCNull constraint, final JvmField field) {
    final JvmAnnotationReference anno = this._jvmTypesBuilder.toAnnotation(constraint, Null.class);
    this.handlePayloadAndMessages(constraint, anno);
    EList<JvmAnnotationReference> _annotations = field.getAnnotations();
    this._jvmTypesBuilder.<JvmAnnotationReference>operator_add(_annotations, anno);
  }
  
  protected void _toConstraintAnnotation(final LDtCFuture constraint, final JvmField field) {
    final JvmAnnotationReference anno = this._jvmTypesBuilder.toAnnotation(constraint, Future.class);
    this.handlePayloadAndMessages(constraint, anno);
    EList<JvmAnnotationReference> _annotations = field.getAnnotations();
    this._jvmTypesBuilder.<JvmAnnotationReference>operator_add(_annotations, anno);
  }
  
  protected void _toConstraintAnnotation(final LDtCPast constraint, final JvmField field) {
    final JvmAnnotationReference anno = this._jvmTypesBuilder.toAnnotation(constraint, Past.class);
    this.handlePayloadAndMessages(constraint, anno);
    EList<JvmAnnotationReference> _annotations = field.getAnnotations();
    this._jvmTypesBuilder.<JvmAnnotationReference>operator_add(_annotations, anno);
  }
  
  protected void _toConstraintAnnotation(final LDtCSize constraint, final JvmField field) {
    final JvmAnnotationReference anno = this._jvmTypesBuilder.toAnnotation(constraint, Size.class);
    int _min = constraint.getMin();
    boolean _greaterEqualsThan = (_min >= 0);
    if (_greaterEqualsThan) {
      this._annotationExtension.addAnnAttr(anno, constraint, "min", Integer.valueOf(constraint.getMin()));
    }
    int _max = constraint.getMax();
    boolean _greaterThan = (_max > 0);
    if (_greaterThan) {
      this._annotationExtension.addAnnAttr(anno, constraint, "max", Integer.valueOf(constraint.getMax()));
    }
    this.handlePayloadAndMessages(constraint, anno);
    EList<JvmAnnotationReference> _annotations = field.getAnnotations();
    this._jvmTypesBuilder.<JvmAnnotationReference>operator_add(_annotations, anno);
  }
  
  protected void _toConstraintAnnotation(final LDtCDigits constraint, final JvmField field) {
    final JvmAnnotationReference anno = this._jvmTypesBuilder.toAnnotation(constraint, Digits.class);
    int _intDigits = constraint.getIntDigits();
    boolean _greaterEqualsThan = (_intDigits >= 0);
    if (_greaterEqualsThan) {
      this._annotationExtension.addAnnAttr(anno, constraint, "integer", Integer.valueOf(constraint.getIntDigits()));
    }
    int _fractionDigits = constraint.getFractionDigits();
    boolean _greaterThan = (_fractionDigits > 0);
    if (_greaterThan) {
      this._annotationExtension.addAnnAttr(anno, constraint, "fraction", Integer.valueOf(constraint.getFractionDigits()));
    }
    this.handlePayloadAndMessages(constraint, anno);
    EList<JvmAnnotationReference> _annotations = field.getAnnotations();
    this._jvmTypesBuilder.<JvmAnnotationReference>operator_add(_annotations, anno);
  }
  
  protected void _toConstraintAnnotation(final LDtCDecimalMax constraint, final JvmField field) {
    final JvmAnnotationReference anno = this._jvmTypesBuilder.toAnnotation(constraint, DecimalMax.class);
    this._annotationExtension.addAnnAttr(anno, constraint, "value", Float.valueOf(constraint.getMax()).toString());
    this.handlePayloadAndMessages(constraint, anno);
    EList<JvmAnnotationReference> _annotations = field.getAnnotations();
    this._jvmTypesBuilder.<JvmAnnotationReference>operator_add(_annotations, anno);
  }
  
  protected void _toConstraintAnnotation(final LDtCDecimalMin constraint, final JvmField field) {
    final JvmAnnotationReference anno = this._jvmTypesBuilder.toAnnotation(constraint, DecimalMin.class);
    this._annotationExtension.addAnnAttr(anno, constraint, "value", Float.valueOf(constraint.getMin()).toString());
    this.handlePayloadAndMessages(constraint, anno);
    EList<JvmAnnotationReference> _annotations = field.getAnnotations();
    this._jvmTypesBuilder.<JvmAnnotationReference>operator_add(_annotations, anno);
  }
  
  protected void _toConstraintAnnotation(final LDtCNumericMax constraint, final JvmField field) {
    final JvmAnnotationReference anno = this._jvmTypesBuilder.toAnnotation(constraint, Max.class);
    this._annotationExtension.addAnnAttr(anno, constraint, "value", Integer.valueOf(constraint.getMax()));
    this.handlePayloadAndMessages(constraint, anno);
    EList<JvmAnnotationReference> _annotations = field.getAnnotations();
    this._jvmTypesBuilder.<JvmAnnotationReference>operator_add(_annotations, anno);
  }
  
  protected void _toConstraintAnnotation(final LDtCNumericMin constraint, final JvmField field) {
    final JvmAnnotationReference anno = this._jvmTypesBuilder.toAnnotation(constraint, Min.class);
    this._annotationExtension.addAnnAttr(anno, constraint, "value", Integer.valueOf(constraint.getMin()));
    this.handlePayloadAndMessages(constraint, anno);
    EList<JvmAnnotationReference> _annotations = field.getAnnotations();
    this._jvmTypesBuilder.<JvmAnnotationReference>operator_add(_annotations, anno);
  }
  
  protected void _toConstraintAnnotation(final LDtCRegEx constraint, final JvmField field) {
    if (((!Objects.equal(constraint.getPattern(), null)) && (!constraint.getPattern().isEmpty()))) {
      final JvmAnnotationReference anno = this._jvmTypesBuilder.toAnnotation(constraint, Pattern.class);
      this._annotationExtension.addAnnAttr(anno, constraint, "regexp", constraint.getPattern());
      this.handlePayloadAndMessages(constraint, anno);
      EList<JvmAnnotationReference> _annotations = field.getAnnotations();
      this._jvmTypesBuilder.<JvmAnnotationReference>operator_add(_annotations, anno);
    }
  }
  
  protected void _internalProcessAnnotation(final LOperation member, final JvmOperation jvmOperation) {
    final Function1<LAnnotationDef, Boolean> _function = (LAnnotationDef it) -> {
      boolean _isExclude = it.isExclude();
      return Boolean.valueOf((!_isExclude));
    };
    final Function1<LAnnotationDef, XAnnotation> _function_1 = (LAnnotationDef it) -> {
      return it.getAnnotation();
    };
    this._jvmTypesBuilder.translateAnnotationsTo(IterableExtensions.<LAnnotationDef, XAnnotation>map(IterableExtensions.<LAnnotationDef>filter(member.getResolvedAnnotations(), _function), _function_1), jvmOperation);
  }
  
  protected void internalProcessAnnotation(final LAnnotationTarget att, final JvmMember jvmType) {
    if (att instanceof LAttribute
         && jvmType instanceof JvmField) {
      _internalProcessAnnotation((LAttribute)att, (JvmField)jvmType);
      return;
    } else if (att instanceof LReference
         && jvmType instanceof JvmField) {
      _internalProcessAnnotation((LReference)att, (JvmField)jvmType);
      return;
    } else if (att instanceof LOperation
         && jvmType instanceof JvmOperation) {
      _internalProcessAnnotation((LOperation)att, (JvmOperation)jvmType);
      return;
    } else if (att instanceof LType
         && jvmType instanceof JvmGenericType) {
      _internalProcessAnnotation((LType)att, (JvmGenericType)jvmType);
      return;
    } else {
      throw new IllegalArgumentException("Unhandled parameter types: " +
        Arrays.<Object>asList(att, jvmType).toString());
    }
  }
  
  public boolean isValidAllowed(final LScalarType type) {
    if (type instanceof LDataType) {
      return _isValidAllowed((LDataType)type);
    } else if (type != null) {
      return _isValidAllowed(type);
    } else if (type == null) {
      return _isValidAllowed((Void)null);
    } else {
      throw new IllegalArgumentException("Unhandled parameter types: " +
        Arrays.<Object>asList(type).toString());
    }
  }
  
  protected void toConstraintAnnotation(final LDatatypeConstraint constraint, final JvmField field) {
    if (constraint instanceof LDtCAssertFalse) {
      _toConstraintAnnotation((LDtCAssertFalse)constraint, field);
      return;
    } else if (constraint instanceof LDtCAssertTrue) {
      _toConstraintAnnotation((LDtCAssertTrue)constraint, field);
      return;
    } else if (constraint instanceof LDtCDecimalMax) {
      _toConstraintAnnotation((LDtCDecimalMax)constraint, field);
      return;
    } else if (constraint instanceof LDtCDecimalMin) {
      _toConstraintAnnotation((LDtCDecimalMin)constraint, field);
      return;
    } else if (constraint instanceof LDtCDigits) {
      _toConstraintAnnotation((LDtCDigits)constraint, field);
      return;
    } else if (constraint instanceof LDtCFuture) {
      _toConstraintAnnotation((LDtCFuture)constraint, field);
      return;
    } else if (constraint instanceof LDtCNotNull) {
      _toConstraintAnnotation((LDtCNotNull)constraint, field);
      return;
    } else if (constraint instanceof LDtCNull) {
      _toConstraintAnnotation((LDtCNull)constraint, field);
      return;
    } else if (constraint instanceof LDtCNumericMax) {
      _toConstraintAnnotation((LDtCNumericMax)constraint, field);
      return;
    } else if (constraint instanceof LDtCNumericMin) {
      _toConstraintAnnotation((LDtCNumericMin)constraint, field);
      return;
    } else if (constraint instanceof LDtCPast) {
      _toConstraintAnnotation((LDtCPast)constraint, field);
      return;
    } else if (constraint instanceof LDtCRegEx) {
      _toConstraintAnnotation((LDtCRegEx)constraint, field);
      return;
    } else if (constraint instanceof LDtCSize) {
      _toConstraintAnnotation((LDtCSize)constraint, field);
      return;
    } else {
      throw new IllegalArgumentException("Unhandled parameter types: " +
        Arrays.<Object>asList(constraint, field).toString());
    }
  }
}
