All Downloads are FREE. Search and download functionalities are using the official Maven repository.

eu.mihosoft.vmf.vmftext.grammar.impl.RuleClassImpl Maven / Gradle / Ivy

The newest version!

package eu.mihosoft.vmf.vmftext.grammar.impl;

// vmf imports
//import eu.mihosoft.vmf.runtime.core.*;
//import eu.mihosoft.vmf.runtime.core.internal.*;
import eu.mihosoft.vcollections.*;
import eu.mihosoft.vmf.vmftext.grammar.*;
import java.beans.PropertyChangeSupport;
import java.beans.PropertyChangeListener;
import java.util.Objects;
import java.util.Arrays;

// property types imports
import eu.mihosoft.vcollections.*;

// implementation

/**
 * An implementation of the model object {@code eu.mihosoft.vmf.vmftext.grammar.RuleClass}.
 */
@SuppressWarnings("deprecation")
class RuleClassImpl implements RuleClass, eu.mihosoft.vmf.runtime.core.internal.VObjectInternalModifiable, VCloneableInternal {

  // --------------------------------------------------------------------
  // --- declaration of member variables
  // --------------------------------------------------------------------


  /*package private*/ eu.mihosoft.vcollections.VList childClasses;
  /*package private*/ eu.mihosoft.vmf.vmftext.grammar.CodeRange codeRange;
  /*package private*/ eu.mihosoft.vcollections.VList customProperties;
  /*package private*/ eu.mihosoft.vcollections.VList customRuleAnnotations;
  /*package private*/ eu.mihosoft.vcollections.VList delegationMethods;
  /*package private*/ eu.mihosoft.vmf.vmftext.grammar.GrammarModel model;
  /*package private*/ java.lang.String name;
  /*package private*/ eu.mihosoft.vcollections.VList properties;
  /*package private*/ boolean root;
  /*package private*/ eu.mihosoft.vmf.vmftext.grammar.RuleClass superClass;
  /*package private*/ eu.mihosoft.vcollections.VList superInterfaces;


// --------------------------------------------------------------------
// --- declaration of delegation variables
// --------------------------------------------------------------------

  private eu.mihosoft.vmf.vmftext.grammar.NameDelegate _vmf_delegate4;
  private eu.mihosoft.vmf.vmftext.grammar.StringUtilDelegate _vmf_delegate5;
  private eu.mihosoft.vmf.vmftext.grammar.CheckPropertiesDelegate _vmf_delegate6;

  private PropertyChangeSupport propertyChanges;

  // referenced by
  private final VList referencedBy = VList.newInstance(new java.util.ArrayList<>());
  // references
  private final VList references = VList.newInstance(new java.util.ArrayList<>());

  // --------------------------------------------------------------------
  // --- public constructors
  // --------------------------------------------------------------------

  public RuleClassImpl() {

// --------------------------------------------------------------------
// --- declaration of delegation methods
// --------------------------------------------------------------------


    if(_vmf_delegate6==null) {
      _vmf_delegate6 = new eu.mihosoft.vmf.vmftext.grammar.CheckPropertiesDelegate();
      _vmf_delegate6.setCaller(this);
    }

    _vmf_delegate6.onRuleClassInstantiated();


// --------------------------------------------------------------------
// --- initialization of default values
// --------------------------------------------------------------------
    // property 0
    // -> no default value is present
    // property 1
    // -> no default value is present
    // property 2
    // -> no default value is present
    // property 3
    // -> no default value is present
    // property 4
    // -> no default value is present
    // property 5
    // -> no default value is present
    // property 6
    // -> no default value is present
    // property 7
    // -> no default value is present
    // property 8
    // -> no default value is present
    // property 9
    // -> no default value is present
    // property 10
    // -> no default value is present

  }

  // --------------------------------------------------------------------
  // --- public getter methods for accessing properties
  // --------------------------------------------------------------------


  @Override
  public eu.mihosoft.vcollections.VList getChildClasses() {

    if(this.childClasses==null) {
      this.childClasses = VList.newInstance(new java.util.ArrayList<>());

      this.childClasses.addChangeListener((evt)-> {
            evt.added().elements().forEach((e)->{

                if(e==null) return;

                // remove element from previous collection
                // TODO use bulk operations if possible
                if(e.getSuperClass()!=null) {
                  e.getSuperClass().getChildClasses().remove(e);
                }

                
                try {
                  java.lang.reflect.Field field =
                    e.getClass().getDeclaredField("superClass");
                  field.setAccessible(true);
                  Object oldOpposite = field.get(e);
                  field.set(e, this);
                  // not generating change event (disableFireEventValue=true)
                } catch (Exception ex) {
                  java.util.logging.Logger.getLogger(
                     RuleClassImpl.class.getName()).
                     log(java.util.logging.Level.SEVERE, null, ex);
                }



                if(e!=null && this!=null) {
                  ((eu.mihosoft.vmf.runtime.core.internal.VObjectInternal)this)._vmf_references().add(e);
                  ((eu.mihosoft.vmf.runtime.core.internal.VObjectInternal)e)._vmf_referencedBy().add(this);
                }

            }); // end of evt.added()

            evt.removed().elements().forEach((e)->{
              if(e==null) return;
                
                try {
                  java.lang.reflect.Field field =
                    e.getClass().getDeclaredField("superClass");
                  field.setAccessible(true);
                  Object oldOpposite = field.get(e);
                  field.set(e, null);
                  // not generating change event (disableFireEventValue=true)
                } catch (Exception ex) {
                  java.util.logging.Logger.getLogger(
                     RuleClassImpl.class.getName()).
                     log(java.util.logging.Level.SEVERE, null, ex);
                }




                if(e!=null && this!=null) {
                  ((eu.mihosoft.vmf.runtime.core.internal.VObjectInternal)this)._vmf_references().add(e);
                  ((eu.mihosoft.vmf.runtime.core.internal.VObjectInternal)e)._vmf_referencedBy().add(this);
                }
            }); // end of evt.removed()
            
        }); // end of change listener

    } // end of "lazy init" if(this.childClasses==null)

    return this.childClasses;

    // return VContainmentUtil.asContainmentList(this.childClasses, "superClass");
  } // end of eu.mihosoft.vcollections.VList getChildClasses()
  @Override
  public eu.mihosoft.vmf.vmftext.grammar.CodeRange getCodeRange() {
    return this.codeRange;

  } // end of eu.mihosoft.vmf.vmftext.grammar.CodeRange getCodeRange()
  @Override
  public eu.mihosoft.vcollections.VList getCustomProperties() {

    if(this.customProperties==null) {
      this.customProperties = VList.newInstance(new java.util.ArrayList<>());

      this.customProperties.addChangeListener((evt)-> {
            evt.added().elements().forEach((e)->{

                if(e==null) return;

                // remove element from previous collection
                // TODO use bulk operations if possible
                if(e.getParent()!=null) {
                  e.getParent().getCustomProperties().remove(e);
                }

                
                try {
                  java.lang.reflect.Field field =
                    e.getClass().getDeclaredField("parent");
                  field.setAccessible(true);
                  Object oldOpposite = field.get(e);
                  field.set(e, this);
                  // not generating change event (disableFireEventValue=true)
                } catch (Exception ex) {
                  java.util.logging.Logger.getLogger(
                     RuleClassImpl.class.getName()).
                     log(java.util.logging.Level.SEVERE, null, ex);
                }



                if(e!=null && this!=null) {
                  ((eu.mihosoft.vmf.runtime.core.internal.VObjectInternal)this)._vmf_references().add(e);
                  ((eu.mihosoft.vmf.runtime.core.internal.VObjectInternal)e)._vmf_referencedBy().add(this);
                }

            }); // end of evt.added()

            evt.removed().elements().forEach((e)->{
              if(e==null) return;
                
                try {
                  java.lang.reflect.Field field =
                    e.getClass().getDeclaredField("parent");
                  field.setAccessible(true);
                  Object oldOpposite = field.get(e);
                  field.set(e, null);
                  // not generating change event (disableFireEventValue=true)
                } catch (Exception ex) {
                  java.util.logging.Logger.getLogger(
                     RuleClassImpl.class.getName()).
                     log(java.util.logging.Level.SEVERE, null, ex);
                }




                if(e!=null && this!=null) {
                  ((eu.mihosoft.vmf.runtime.core.internal.VObjectInternal)this)._vmf_references().add(e);
                  ((eu.mihosoft.vmf.runtime.core.internal.VObjectInternal)e)._vmf_referencedBy().add(this);
                }
            }); // end of evt.removed()
            
        }); // end of change listener

    } // end of "lazy init" if(this.customProperties==null)

    return this.customProperties;

    // return VContainmentUtil.asContainmentList(this.customProperties, "parent");
  } // end of eu.mihosoft.vcollections.VList getCustomProperties()
  @Override
  public eu.mihosoft.vcollections.VList getCustomRuleAnnotations() {

    if(this.customRuleAnnotations==null) {
      this.customRuleAnnotations = VList.newInstance(new java.util.ArrayList<>());

      this.customRuleAnnotations.addChangeListener((evt)-> {
            evt.added().elements().forEach((e)->{

                if(e==null) return;

                // remove element from previous collection
                // TODO use bulk operations if possible
                if(e.getParent()!=null) {
                  e.getParent().getCustomRuleAnnotations().remove(e);
                }

                
                try {
                  java.lang.reflect.Field field =
                    e.getClass().getDeclaredField("parent");
                  field.setAccessible(true);
                  Object oldOpposite = field.get(e);
                  field.set(e, this);
                  // not generating change event (disableFireEventValue=true)
                } catch (Exception ex) {
                  java.util.logging.Logger.getLogger(
                     RuleClassImpl.class.getName()).
                     log(java.util.logging.Level.SEVERE, null, ex);
                }



                if(e!=null && this!=null) {
                  ((eu.mihosoft.vmf.runtime.core.internal.VObjectInternal)this)._vmf_references().add(e);
                  ((eu.mihosoft.vmf.runtime.core.internal.VObjectInternal)e)._vmf_referencedBy().add(this);
                }

            }); // end of evt.added()

            evt.removed().elements().forEach((e)->{
              if(e==null) return;
                
                try {
                  java.lang.reflect.Field field =
                    e.getClass().getDeclaredField("parent");
                  field.setAccessible(true);
                  Object oldOpposite = field.get(e);
                  field.set(e, null);
                  // not generating change event (disableFireEventValue=true)
                } catch (Exception ex) {
                  java.util.logging.Logger.getLogger(
                     RuleClassImpl.class.getName()).
                     log(java.util.logging.Level.SEVERE, null, ex);
                }




                if(e!=null && this!=null) {
                  ((eu.mihosoft.vmf.runtime.core.internal.VObjectInternal)this)._vmf_references().add(e);
                  ((eu.mihosoft.vmf.runtime.core.internal.VObjectInternal)e)._vmf_referencedBy().add(this);
                }
            }); // end of evt.removed()
            
        }); // end of change listener

    } // end of "lazy init" if(this.customRuleAnnotations==null)

    return this.customRuleAnnotations;

    // return VContainmentUtil.asContainmentList(this.customRuleAnnotations, "parent");
  } // end of eu.mihosoft.vcollections.VList getCustomRuleAnnotations()
  @Override
  public eu.mihosoft.vcollections.VList getDelegationMethods() {

    if(this.delegationMethods==null) {
      this.delegationMethods = VList.newInstance(new java.util.ArrayList<>());

      this.delegationMethods.addChangeListener((evt)-> {
            evt.added().elements().forEach((e)->{

                if(e==null) return;

                // remove element from previous collection
                // TODO use bulk operations if possible
                if(e.getParent()!=null) {
                  e.getParent().getDelegationMethods().remove(e);
                }

                
                try {
                  java.lang.reflect.Field field =
                    e.getClass().getDeclaredField("parent");
                  field.setAccessible(true);
                  Object oldOpposite = field.get(e);
                  field.set(e, this);
                  // not generating change event (disableFireEventValue=true)
                } catch (Exception ex) {
                  java.util.logging.Logger.getLogger(
                     RuleClassImpl.class.getName()).
                     log(java.util.logging.Level.SEVERE, null, ex);
                }



                if(e!=null && this!=null) {
                  ((eu.mihosoft.vmf.runtime.core.internal.VObjectInternal)this)._vmf_references().add(e);
                  ((eu.mihosoft.vmf.runtime.core.internal.VObjectInternal)e)._vmf_referencedBy().add(this);
                }

            }); // end of evt.added()

            evt.removed().elements().forEach((e)->{
              if(e==null) return;
                
                try {
                  java.lang.reflect.Field field =
                    e.getClass().getDeclaredField("parent");
                  field.setAccessible(true);
                  Object oldOpposite = field.get(e);
                  field.set(e, null);
                  // not generating change event (disableFireEventValue=true)
                } catch (Exception ex) {
                  java.util.logging.Logger.getLogger(
                     RuleClassImpl.class.getName()).
                     log(java.util.logging.Level.SEVERE, null, ex);
                }




                if(e!=null && this!=null) {
                  ((eu.mihosoft.vmf.runtime.core.internal.VObjectInternal)this)._vmf_references().add(e);
                  ((eu.mihosoft.vmf.runtime.core.internal.VObjectInternal)e)._vmf_referencedBy().add(this);
                }
            }); // end of evt.removed()
            
        }); // end of change listener

    } // end of "lazy init" if(this.delegationMethods==null)

    return this.delegationMethods;

    // return VContainmentUtil.asContainmentList(this.delegationMethods, "parent");
  } // end of eu.mihosoft.vcollections.VList getDelegationMethods()
  @Override
  public eu.mihosoft.vmf.vmftext.grammar.GrammarModel getModel() {
    return this.model;

  } // end of eu.mihosoft.vmf.vmftext.grammar.GrammarModel getModel()
  @Override
  public java.lang.String getName() {
    return this.name;

  } // end of java.lang.String getName()
  @Override
  public eu.mihosoft.vcollections.VList getProperties() {

    if(this.properties==null) {
      this.properties = VList.newInstance(new java.util.ArrayList<>());

      this.properties.addChangeListener((evt)-> {
            evt.added().elements().forEach((e)->{

                if(e==null) return;

                // remove element from previous collection
                // TODO use bulk operations if possible
                if(e.getParent()!=null) {
                  e.getParent().getProperties().remove(e);
                }

                
                try {
                  java.lang.reflect.Field field =
                    e.getClass().getDeclaredField("parent");
                  field.setAccessible(true);
                  Object oldOpposite = field.get(e);
                  field.set(e, this);
                  // not generating change event (disableFireEventValue=true)
                } catch (Exception ex) {
                  java.util.logging.Logger.getLogger(
                     RuleClassImpl.class.getName()).
                     log(java.util.logging.Level.SEVERE, null, ex);
                }



                if(e!=null && this!=null) {
                  ((eu.mihosoft.vmf.runtime.core.internal.VObjectInternal)this)._vmf_references().add(e);
                  ((eu.mihosoft.vmf.runtime.core.internal.VObjectInternal)e)._vmf_referencedBy().add(this);
                }

            }); // end of evt.added()

            evt.removed().elements().forEach((e)->{
              if(e==null) return;
                
                try {
                  java.lang.reflect.Field field =
                    e.getClass().getDeclaredField("parent");
                  field.setAccessible(true);
                  Object oldOpposite = field.get(e);
                  field.set(e, null);
                  // not generating change event (disableFireEventValue=true)
                } catch (Exception ex) {
                  java.util.logging.Logger.getLogger(
                     RuleClassImpl.class.getName()).
                     log(java.util.logging.Level.SEVERE, null, ex);
                }




                if(e!=null && this!=null) {
                  ((eu.mihosoft.vmf.runtime.core.internal.VObjectInternal)this)._vmf_references().add(e);
                  ((eu.mihosoft.vmf.runtime.core.internal.VObjectInternal)e)._vmf_referencedBy().add(this);
                }
            }); // end of evt.removed()
            
        }); // end of change listener

    } // end of "lazy init" if(this.properties==null)

    return this.properties;

    // return VContainmentUtil.asContainmentList(this.properties, "parent");
  } // end of eu.mihosoft.vcollections.VList getProperties()
  @Override
  public boolean isRoot() {
    return this.root;

  } // end of boolean isRoot()
  @Override
  public eu.mihosoft.vmf.vmftext.grammar.RuleClass getSuperClass() {
    return this.superClass;

  } // end of eu.mihosoft.vmf.vmftext.grammar.RuleClass getSuperClass()
  @Override
  public eu.mihosoft.vcollections.VList getSuperInterfaces() {
    if(this.superInterfaces==null) {
      this.superInterfaces = VList.newInstance(new java.util.ArrayList<>());
    } // end of "lazy init" if(this.superInterfaces==null)
    return this.superInterfaces;

  } // end of eu.mihosoft.vcollections.VList getSuperInterfaces()

  // --------------------------------------------------------------------
  // --- public setter methods for setting properties
  // --------------------------------------------------------------------


   @Override
   public void setCodeRange(eu.mihosoft.vmf.vmftext.grammar.CodeRange codeRange) {

    // return early if identical value has been set
    if (this.codeRange == codeRange) {
      return;
    }

    // set the new value
    eu.mihosoft.vmf.vmftext.grammar.CodeRange oldValue = this.codeRange;
    this.codeRange = codeRange;

    // fire property change event
    _vmf_firePropertyChangeIfListenersArePresent("codeRange", oldValue, this.codeRange);
 

      if(this.codeRange!=null && this!=null) {
        ((eu.mihosoft.vmf.runtime.core.internal.VObjectInternal)this)._vmf_references().add(this.codeRange);
        ((eu.mihosoft.vmf.runtime.core.internal.VObjectInternal)this.codeRange)._vmf_referencedBy().add(this);
      }

      if(oldValue!=null && this!=null) {
        ((eu.mihosoft.vmf.runtime.core.internal.VObjectInternal)this)._vmf_references().add(oldValue);
        ((eu.mihosoft.vmf.runtime.core.internal.VObjectInternal)oldValue)._vmf_referencedBy().add(this);
      }
  } // setterDeclaration (setter method)
      @Override
  public void setModel(eu.mihosoft.vmf.vmftext.grammar.GrammarModel model) {

    // opposite is a collection type. we just need to add this to the
    // opposite collection which will handle the containment just fine

    // nothing to do, values are identical
    if(this.model == model) {
      return;
    }

    // remove this from previous opposite
    if(this.model!=null) {
        this.model.getRuleClasses().remove(this);
    }

    // add this to new opposite
    if(model!=null) {
        model.getRuleClasses().add(this);
    }
  }
    @Override
   public void setName(java.lang.String name) {

    // return early if identical value has been set
    if (this.name == name) {
      return;
    }

    // set the new value
    java.lang.String oldValue = this.name;
    this.name = name;

    // fire property change event
    _vmf_firePropertyChangeIfListenersArePresent("name", oldValue, this.name);
 

  } // setterDeclaration (setter method)
     @Override
   public void setRoot(boolean root) {

    // return early if identical value has been set
    if (this.root == root) {
      return;
    }

    // set the new value
    boolean oldValue = this.root;
    this.root = root;

    // fire property change event
    _vmf_firePropertyChangeIfListenersArePresent("root", oldValue, this.root);
 

  } // setterDeclaration (setter method)
      @Override
  public void setSuperClass(eu.mihosoft.vmf.vmftext.grammar.RuleClass superClass) {

    // opposite is a collection type. we just need to add this to the
    // opposite collection which will handle the containment just fine

    // nothing to do, values are identical
    if(this.superClass == superClass) {
      return;
    }

    // remove this from previous opposite
    if(this.superClass!=null) {
        this.superClass.getChildClasses().remove(this);
    }

    // add this to new opposite
    if(superClass!=null) {
        superClass.getChildClasses().add(this);
    }
  }
    
  // --------------------------------------------------------------------
  // --- Object methods (equals(), toString() etc.)
  // --------------------------------------------------------------------


  // --------------------------- BEGIN TO_STRING -----------------------------
  @Override
  public String toString() {

    boolean entry = _vmf_getThreadLocalToString().get().isEmpty();
    try {
        // test if "this" has been seen before
        // implementation based on http://stackoverflow.com/a/11300376/1493549
        boolean isImmutable = (this instanceof eu.mihosoft.vmf.runtime.core.Immutable);
        if (!isImmutable && _vmf_getThreadLocalToString().get().containsKey(this)) {
          return "{skipping recursion}";
        } else {
          if(!isImmutable) {
            _vmf_getThreadLocalToString().get().put(this, null);
          }
          entry = true;
        }
        return "{\"@type\":\"RuleClass\"" +
        ", " + (this.childClasses==null?"[]":this.childClasses) +
          ", \"codeRange\": \"" + this.codeRange + "\"" +
          ", " + (this.customProperties==null?"[]":this.customProperties) +
          ", " + (this.customRuleAnnotations==null?"[]":this.customRuleAnnotations) +
          ", " + (this.delegationMethods==null?"[]":this.delegationMethods) +
          ", \"model\": \"" + this.model + "\"" +
          ", \"name\": \"" + this.name + "\"" +
          ", " + (this.properties==null?"[]":this.properties) +
          ", \"root\": \"" + this.root + "\"" +
           ", \"superInterfaces\": \"" + this.superInterfaces + "\"" +
           "}";
    } finally {
        if (entry) {
            _vmf_getThreadLocalToString().get().clear();
            _vmf_fToStringChecker = null;
        }
    }
  }

  private ThreadLocal> _vmf_getThreadLocalToString() {
    if (_vmf_fToStringChecker==null) {
      _vmf_fToStringChecker = ThreadLocal.withInitial(
        () -> new java.util.IdentityHashMap<>());
    }

    return _vmf_fToStringChecker;
  }

  private ThreadLocal> _vmf_fToStringChecker;

  // end toString()
  // ---------------------------- END TO_STRING ------------------------------


  // --------------------------- BEGIN EQUALITY -----------------------------
  @Override
  public boolean equals(Object o) {

    boolean entry = _vmf_getThreadLocalEquals().get().isEmpty();
    try {
      // test if the object pair (this,o) has been checked before
      boolean isImmutable = (o instanceof eu.mihosoft.vmf.runtime.core.Immutable);
      if (!isImmutable && _vmf_getThreadLocalEquals().get().containsKey(new EqualsPair(this, o))) {
        // This pair has been seen before. That's why we return true now.
        // If this pair wasn't equal, we wouldn't need to do a second
        // comparison. Returning 'true' is equivalent to ignoring this
        // particular test in the calling 'equals()' method.
        return true;
      } else {
        if(!isImmutable) {
          _vmf_getThreadLocalEquals().get().put(new EqualsPair(this, o), null);
        }
        entry = true;
      }

      if (o==null) return false;
      else if (this==o) return true;

      // if object is read-only wrapper then unwrap the actual object
      if(o instanceof ReadOnlyRuleClassImpl) {
        o = ((ReadOnlyRuleClassImpl)o)._vmf_getMutableObject();
      }

      // -- try our interface/implementation --

      // perform the actual comparison for each property
      if (o instanceof RuleClassImpl) {
        RuleClassImpl other = (RuleClassImpl) o;
        return           _vmf_equals(this.childClasses, other.childClasses) &&
          _vmf_equals(this.codeRange, other.codeRange) &&
          _vmf_equals(this.customProperties, other.customProperties) &&
          _vmf_equals(this.customRuleAnnotations, other.customRuleAnnotations) &&
          _vmf_equals(this.delegationMethods, other.delegationMethods) &&
          _vmf_equals(this.model, other.model) &&
          _vmf_equals(this.name, other.name) &&
          _vmf_equals(this.properties, other.properties) &&
          _vmf_equals(this.root, other.root) &&
          _vmf_equals(this.superInterfaces, other.superInterfaces);
      }

      // -- try every implementation that implements our interface --

      // no implementation matched. we end the comparison.
      return false;
    } finally {
      if (entry) {
          _vmf_getThreadLocalEquals().get().clear();
          _vmf_fEqualsChecker = null;
      }
    }
  } // end equals()

  private static boolean _vmf_equals(Object o1, Object o2) {
    boolean oneAndOnlyOneIsNull = (o1 == null) != (o2 == null);
    boolean collectionType = o1 instanceof VList || o2 instanceof VList;

    // since we support lazy initialization for collections,
    // uninitialized empty collection values are defined as equal to null
    // otherwise we would have to initialize these values, which would then
    // neutralize or even negate the positive effect of lazy initialization
    if(oneAndOnlyOneIsNull && collectionType) {
      if(o1==null) {
        return ((VList)o2).isEmpty();
      } else {
        return ((VList)o1).isEmpty();
      }
    } else {
      return Objects.equals(o1,o2);
    }
  }

  @Override
  public int hashCode() {
      boolean entry = _vmf_getThreadLocalHashCode().get().isEmpty();
      try {
          // test if "this class" has been seen before
          //
          // WARNING we use `System.identityHashCode(this)` to prevent recursive
          // hashCode() calls before we do the actual test. This would eliminate
          // the effect of the thread-local map
          if (_vmf_getThreadLocalHashCode().get().containsKey(System.identityHashCode(this))) {
            return 0; // already visited
          } else {
            _vmf_getThreadLocalHashCode().get().put(System.identityHashCode(this), null);
            int value = _vmf_deepHashCode(
            this.childClasses,            this.codeRange,            this.customProperties,            this.customRuleAnnotations,            this.delegationMethods,            this.model,            this.name,            this.properties,            this.root,            this.superInterfaces        );
            entry = true;
            return value;
          }

      } finally {
          if (entry) {
              _vmf_getThreadLocalHashCode().get().clear();
              _vmf_fHashCodeChecker = null;
          }
      }

  } // end hashCode()

  // fixes 'array discovery problems' with the 'Objects.hash(...)' method
  // see http://stackoverflow.com/questions/30385018/how-to-use-java-7-objects-hash-with-arrays
  private int _vmf_deepHashCode(Object... fields) {
      // WARNING we are not allowed to pass arrays that contain itself
      //         or are contained in nested arrays
      return Arrays.deepHashCode(fields);
  } // end _vmf_deepHashCode()

  /**
   * The purpose of this class is to store a pair of objects used for equals().
   * This class's equals() method checks equality by object identity. Same
   * for hashCode() which uses identity hashes of 'first' and 'second' to
   * compute the hash.
   *
   * This class can be used in conjunction with a regular HashMap to get
   * similar results to an IdentityHashMap, except that in this case identity
   * pairs can be used. And we don't have to use a map implementation that is
   * deliberately broken by design.
   */
  private static class EqualsPair {

      final Object first;
      final Object second;

      public EqualsPair(Object first, Object second) {
          this.first = first;
          this.second = second;
      }

      @Override
      public int hashCode() {
          return Objects.hash(System.identityHashCode(first),
                  System.identityHashCode(second));
      }

      @Override
      public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final EqualsPair other = (EqualsPair) obj;
        if (this.first!=other.first) {
            return false;
        }
        if (this.second!=other.second) {
            return false;
        }
        return true;
      }
  }

  private ThreadLocal> _vmf_getThreadLocalEquals() {
    if (_vmf_fEqualsChecker==null) {
      _vmf_fEqualsChecker = ThreadLocal.withInitial(
        () -> new java.util.HashMap<>());
    }

    return _vmf_fEqualsChecker;
  }

  private ThreadLocal> _vmf_getThreadLocalHashCode() {
    if (_vmf_fHashCodeChecker==null) {
      _vmf_fHashCodeChecker = ThreadLocal.withInitial(
        () -> new java.util.HashMap<>());
    }

    return _vmf_fHashCodeChecker;
  }

  private ThreadLocal> _vmf_fEqualsChecker;


  private ThreadLocal> _vmf_fHashCodeChecker;
  // ---------------------------- END EQUALITY ------------------------------


  // --------------------------- BEGIN CLONING -----------------------------
  /**
   * Package private copy constructor.
   * It creates a deep or shallow copy of the specified other object.
   * @param other other object
   * @param deepCopy defines whether to perform a deep copy
   */
  RuleClassImpl (
    RuleClassImpl other,
    boolean deepCopy, java.util.IdentityHashMap identityMap
  ) {
    identityMap.put(other,this);

    if(deepCopy) {
      if(other.childClasses!=null) {
        // element type is a model type
        for(RuleClass e : other.childClasses) {
          // TODO do a bulk operation instead
          eu.mihosoft.vmf.runtime.core.internal.VObjectInternal eClone = (eu.mihosoft.vmf.runtime.core.internal.VObjectInternal)(RuleClass)((VCloneableInternal)e)._vmf_deepCopy(identityMap);
          this.getChildClasses().add((RuleClass)eClone);
        }
       } else {
        // nothing to copy
      }
    } else {
      this.childClasses = other.childClasses;
    }
    if(this.childClasses!=null) {
      this.childClasses.forEach((e) -> {
          
        try {
          java.lang.reflect.Field field =
            e.getClass().getDeclaredField("superClass");
          field.setAccessible(true);
          Object oldOpposite = field.get(e);
          field.set(e, this);
          // not generating change event (disableFireEventValue=true)
        } catch (Exception ex) {
          java.util.logging.Logger.getLogger(
             RuleClassImpl.class.getName()).
             log(java.util.logging.Level.SEVERE, null, ex);
        }

      });
    }
          // property type is a model type
      if(deepCopy) {
        if(other.codeRange!=null) {
          this.setCodeRange((eu.mihosoft.vmf.vmftext.grammar.CodeRange)((VCloneableInternal)other.codeRange)._vmf_deepCopy(identityMap));
        }
      } else {
        this.codeRange = other.codeRange;
      }
       if(deepCopy) {
      if(other.customProperties!=null) {
        // element type is a model type
        for(Property e : other.customProperties) {
          // TODO do a bulk operation instead
          eu.mihosoft.vmf.runtime.core.internal.VObjectInternal eClone = (eu.mihosoft.vmf.runtime.core.internal.VObjectInternal)(Property)((VCloneableInternal)e)._vmf_deepCopy(identityMap);
          this.getCustomProperties().add((Property)eClone);
        }
       } else {
        // nothing to copy
      }
    } else {
      this.customProperties = other.customProperties;
    }
    if(this.customProperties!=null) {
      this.customProperties.forEach((e) -> {
          
        try {
          java.lang.reflect.Field field =
            e.getClass().getDeclaredField("parent");
          field.setAccessible(true);
          Object oldOpposite = field.get(e);
          field.set(e, this);
          // not generating change event (disableFireEventValue=true)
        } catch (Exception ex) {
          java.util.logging.Logger.getLogger(
             RuleClassImpl.class.getName()).
             log(java.util.logging.Level.SEVERE, null, ex);
        }

      });
    }
       if(deepCopy) {
      if(other.customRuleAnnotations!=null) {
        // element type is a model type
        for(RuleAnnotation e : other.customRuleAnnotations) {
          // TODO do a bulk operation instead
          eu.mihosoft.vmf.runtime.core.internal.VObjectInternal eClone = (eu.mihosoft.vmf.runtime.core.internal.VObjectInternal)(RuleAnnotation)((VCloneableInternal)e)._vmf_deepCopy(identityMap);
          this.getCustomRuleAnnotations().add((RuleAnnotation)eClone);
        }
       } else {
        // nothing to copy
      }
    } else {
      this.customRuleAnnotations = other.customRuleAnnotations;
    }
    if(this.customRuleAnnotations!=null) {
      this.customRuleAnnotations.forEach((e) -> {
          
        try {
          java.lang.reflect.Field field =
            e.getClass().getDeclaredField("parent");
          field.setAccessible(true);
          Object oldOpposite = field.get(e);
          field.set(e, this);
          // not generating change event (disableFireEventValue=true)
        } catch (Exception ex) {
          java.util.logging.Logger.getLogger(
             RuleClassImpl.class.getName()).
             log(java.util.logging.Level.SEVERE, null, ex);
        }

      });
    }
       if(deepCopy) {
      if(other.delegationMethods!=null) {
        // element type is a model type
        for(DelegationMethod e : other.delegationMethods) {
          // TODO do a bulk operation instead
          eu.mihosoft.vmf.runtime.core.internal.VObjectInternal eClone = (eu.mihosoft.vmf.runtime.core.internal.VObjectInternal)(DelegationMethod)((VCloneableInternal)e)._vmf_deepCopy(identityMap);
          this.getDelegationMethods().add((DelegationMethod)eClone);
        }
       } else {
        // nothing to copy
      }
    } else {
      this.delegationMethods = other.delegationMethods;
    }
    if(this.delegationMethods!=null) {
      this.delegationMethods.forEach((e) -> {
          
        try {
          java.lang.reflect.Field field =
            e.getClass().getDeclaredField("parent");
          field.setAccessible(true);
          Object oldOpposite = field.get(e);
          field.set(e, this);
          // not generating change event (disableFireEventValue=true)
        } catch (Exception ex) {
          java.util.logging.Logger.getLogger(
             RuleClassImpl.class.getName()).
             log(java.util.logging.Level.SEVERE, null, ex);
        }

      });
    }
          // property type is a model type
      if(deepCopy) {
        if(other.model!=null) {
          this.setModel((eu.mihosoft.vmf.vmftext.grammar.GrammarModel)((VCloneableInternal)other.model)._vmf_deepCopy(identityMap));
        }
      } else {
        this.model = other.model;
      }
           // property type is an external type (TODO implement cloning strategy)
      this.setName(other.name);
       if(deepCopy) {
      if(other.properties!=null) {
        // element type is a model type
        for(Property e : other.properties) {
          // TODO do a bulk operation instead
          eu.mihosoft.vmf.runtime.core.internal.VObjectInternal eClone = (eu.mihosoft.vmf.runtime.core.internal.VObjectInternal)(Property)((VCloneableInternal)e)._vmf_deepCopy(identityMap);
          this.getProperties().add((Property)eClone);
        }
       } else {
        // nothing to copy
      }
    } else {
      this.properties = other.properties;
    }
    if(this.properties!=null) {
      this.properties.forEach((e) -> {
          
        try {
          java.lang.reflect.Field field =
            e.getClass().getDeclaredField("parent");
          field.setAccessible(true);
          Object oldOpposite = field.get(e);
          field.set(e, this);
          // not generating change event (disableFireEventValue=true)
        } catch (Exception ex) {
          java.util.logging.Logger.getLogger(
             RuleClassImpl.class.getName()).
             log(java.util.logging.Level.SEVERE, null, ex);
        }

      });
    }
           // property type is an external type (TODO implement cloning strategy)
      this.setRoot(other.root);
        if(deepCopy) {
      if(other.superInterfaces!=null) {
         // element type is an external type (TODO implement cloning strategy)
        this.getSuperInterfaces().addAll(other.superInterfaces);
       } else {
        // nothing to copy
      }
    } else {
      this.superInterfaces = other.superInterfaces;
    }
    
   } // end copy constructor

   @Override
   public RuleClassImpl _vmf_deepCopy(java.util.IdentityHashMap identityMap) {
      if(identityMap.containsKey(this)) {
        return (RuleClassImpl)identityMap.get(this);
      } else {
        RuleClassImpl clonedVal = new RuleClassImpl(this, true, identityMap);
        return clonedVal;
      }
   }

   @Override
   public RuleClassImpl _vmf_shallowCopy(java.util.IdentityHashMap identityMap) {
      if(identityMap.containsKey(this)) {
        return (RuleClassImpl)identityMap.get(this);
      } else {
        RuleClassImpl clonedVal = new RuleClassImpl(this, false, identityMap);
        return clonedVal;
      }
   }
  @Override
  public RuleClassImpl clone() /*throws CloneNotSupportedException*/ {
    // http://stackoverflow.com/questions/12886036/deep-copying-a-graph-structure
    // http://softwareengineering.stackexchange.com/questions/228848/how-does-java-handle-cyclic-data-references-when-serializing-an-object
    // https://gist.github.com/kanrourou/47223bdaf481505d4c7e
    // http://www.programcreek.com/2012/12/leetcode-clone-graph-java/
    java.util.IdentityHashMap identityMap =
      new java.util.IdentityHashMap<>();
    return _vmf_deepCopy(identityMap);
  }
  // ---------------------------- END CLONING ------------------------------


// --------------------------------------------------------------------
// --- Builder methods
// --------------------------------------------------------------------

public static class BuilderImpl implements RuleClass.Builder {

  private eu.mihosoft.vcollections.VList childClasses;
  private eu.mihosoft.vmf.vmftext.grammar.CodeRange codeRange;
  private eu.mihosoft.vcollections.VList customProperties;
  private eu.mihosoft.vcollections.VList customRuleAnnotations;
  private eu.mihosoft.vcollections.VList delegationMethods;
  private eu.mihosoft.vmf.vmftext.grammar.GrammarModel model;
  private java.lang.String name;
  private eu.mihosoft.vcollections.VList properties;
  private boolean root;
  private eu.mihosoft.vmf.vmftext.grammar.RuleClass superClass;
  private eu.mihosoft.vcollections.VList superInterfaces;

  private boolean appendCollections = true;

  public BuilderImpl() {}

    public RuleClass.Builder withChildClasses(eu.mihosoft.vcollections.VList childClasses) {
      // ensure that this collection property is really immutable
      this.childClasses = VList.newInstance(
        java.util.Collections.
        unmodifiableList(
          new java.util.ArrayList(childClasses)
        )
      );
      return this;
    }
    public RuleClass.Builder withCodeRange(eu.mihosoft.vmf.vmftext.grammar.CodeRange codeRange) {
      this.codeRange = codeRange;
      return this;
    }
    public RuleClass.Builder withCustomProperties(eu.mihosoft.vcollections.VList customProperties) {
      // ensure that this collection property is really immutable
      this.customProperties = VList.newInstance(
        java.util.Collections.
        unmodifiableList(
          new java.util.ArrayList(customProperties)
        )
      );
      return this;
    }
    public RuleClass.Builder withCustomRuleAnnotations(eu.mihosoft.vcollections.VList customRuleAnnotations) {
      // ensure that this collection property is really immutable
      this.customRuleAnnotations = VList.newInstance(
        java.util.Collections.
        unmodifiableList(
          new java.util.ArrayList(customRuleAnnotations)
        )
      );
      return this;
    }
    public RuleClass.Builder withDelegationMethods(eu.mihosoft.vcollections.VList delegationMethods) {
      // ensure that this collection property is really immutable
      this.delegationMethods = VList.newInstance(
        java.util.Collections.
        unmodifiableList(
          new java.util.ArrayList(delegationMethods)
        )
      );
      return this;
    }
    public RuleClass.Builder withModel(eu.mihosoft.vmf.vmftext.grammar.GrammarModel model) {
      this.model = model;
      return this;
    }
    public RuleClass.Builder withName(java.lang.String name) {
      this.name = name;
      return this;
    }
    public RuleClass.Builder withProperties(eu.mihosoft.vcollections.VList properties) {
      // ensure that this collection property is really immutable
      this.properties = VList.newInstance(
        java.util.Collections.
        unmodifiableList(
          new java.util.ArrayList(properties)
        )
      );
      return this;
    }
    public RuleClass.Builder withRoot(boolean root) {
      this.root = root;
      return this;
    }
    public RuleClass.Builder withSuperInterfaces(eu.mihosoft.vcollections.VList superInterfaces) {
      // ensure that this collection property is really immutable
      this.superInterfaces = VList.newInstance(
        java.util.Collections.
        unmodifiableList(
          new java.util.ArrayList(superInterfaces)
        )
      );
      return this;
    }

  public Builder appendCollections(boolean value) {
    this.appendCollections = value;
    return this;
  }

  public RuleClass build() {
    RuleClassImpl result = new RuleClassImpl();
    if(this.childClasses !=null) {
      result.getChildClasses().addAll(this.childClasses);
    }
    result.codeRange = this.codeRange;
    // PROP: codeRange
        
      if(result.codeRange!=null && result!=null) {
        ((eu.mihosoft.vmf.runtime.core.internal.VObjectInternal)result)._vmf_references().add(result.codeRange);
        ((eu.mihosoft.vmf.runtime.core.internal.VObjectInternal)result.codeRange)._vmf_referencedBy().add(result);
      }

    if(this.customProperties !=null) {
      result.getCustomProperties().addAll(this.customProperties);
    }
    if(this.customRuleAnnotations !=null) {
      result.getCustomRuleAnnotations().addAll(this.customRuleAnnotations);
    }
    if(this.delegationMethods !=null) {
      result.getDelegationMethods().addAll(this.delegationMethods);
    }
    result.model = this.model;
    // PROP: model
        
      if(result.model!=null && result!=null) {
        ((eu.mihosoft.vmf.runtime.core.internal.VObjectInternal)result)._vmf_references().add(result.model);
        ((eu.mihosoft.vmf.runtime.core.internal.VObjectInternal)result.model)._vmf_referencedBy().add(result);
      }

    result.name = this.name;
    if(this.properties !=null) {
      result.getProperties().addAll(this.properties);
    }
    result.root = this.root;
    result.superClass = this.superClass;
    // PROP: superClass
        
      if(result.superClass!=null && result!=null) {
        ((eu.mihosoft.vmf.runtime.core.internal.VObjectInternal)result)._vmf_references().add(result.superClass);
        ((eu.mihosoft.vmf.runtime.core.internal.VObjectInternal)result.superClass)._vmf_referencedBy().add(result);
      }

    if(this.superInterfaces !=null) {
      result.getSuperInterfaces().addAll(this.superInterfaces);
    }
    return result;
  }

  public Builder applyFrom(RuleClass o) {
      if(!this.appendCollections||this.childClasses==null) {
        // ensure that this collection property is really immutable
        this.childClasses = VList.newInstance(
          java.util.Collections.
          unmodifiableList(
              new java.util.ArrayList(o.getChildClasses())
          )
        );
      } else {
        this.childClasses.addAll(o.getChildClasses());
      }
      this.codeRange = o.getCodeRange();
      if(!this.appendCollections||this.customProperties==null) {
        // ensure that this collection property is really immutable
        this.customProperties = VList.newInstance(
          java.util.Collections.
          unmodifiableList(
              new java.util.ArrayList(o.getCustomProperties())
          )
        );
      } else {
        this.customProperties.addAll(o.getCustomProperties());
      }
      if(!this.appendCollections||this.customRuleAnnotations==null) {
        // ensure that this collection property is really immutable
        this.customRuleAnnotations = VList.newInstance(
          java.util.Collections.
          unmodifiableList(
              new java.util.ArrayList(o.getCustomRuleAnnotations())
          )
        );
      } else {
        this.customRuleAnnotations.addAll(o.getCustomRuleAnnotations());
      }
      if(!this.appendCollections||this.delegationMethods==null) {
        // ensure that this collection property is really immutable
        this.delegationMethods = VList.newInstance(
          java.util.Collections.
          unmodifiableList(
              new java.util.ArrayList(o.getDelegationMethods())
          )
        );
      } else {
        this.delegationMethods.addAll(o.getDelegationMethods());
      }
      this.model = o.getModel();
      this.name = o.getName();
      if(!this.appendCollections||this.properties==null) {
        // ensure that this collection property is really immutable
        this.properties = VList.newInstance(
          java.util.Collections.
          unmodifiableList(
              new java.util.ArrayList(o.getProperties())
          )
        );
      } else {
        this.properties.addAll(o.getProperties());
      }
      this.root = o.isRoot();
      this.superClass = o.getSuperClass();
      if(!this.appendCollections||this.superInterfaces==null) {
        // ensure that this collection property is really immutable
        this.superInterfaces = VList.newInstance(
          java.util.Collections.
          unmodifiableList(
              new java.util.ArrayList(o.getSuperInterfaces())
          )
        );
      } else {
        this.superInterfaces.addAll(o.getSuperInterfaces());
      }

    return this;
  }
  public Builder applyTo(RuleClass o) {

      if(!this.appendCollections) {
        o.getChildClasses().clear();
      }
      o.getChildClasses().addAll(childClasses);
      o.setCodeRange(codeRange);
      if(!this.appendCollections) {
        o.getCustomProperties().clear();
      }
      o.getCustomProperties().addAll(customProperties);
      if(!this.appendCollections) {
        o.getCustomRuleAnnotations().clear();
      }
      o.getCustomRuleAnnotations().addAll(customRuleAnnotations);
      if(!this.appendCollections) {
        o.getDelegationMethods().clear();
      }
      o.getDelegationMethods().addAll(delegationMethods);
      o.setName(name);
      if(!this.appendCollections) {
        o.getProperties().clear();
      }
      o.getProperties().addAll(properties);
      o.setRoot(root);
      if(!this.appendCollections) {
        o.getSuperInterfaces().clear();
      }
      o.getSuperInterfaces().addAll(superInterfaces);

    return this;
  }
} // end class BuilderImpl


// --------------------------------------------------------------------
// --- declaration of delegation methods
// --------------------------------------------------------------------

  public java.lang.String nameWithLower() {

    if(_vmf_delegate4==null) {
      _vmf_delegate4 = new eu.mihosoft.vmf.vmftext.grammar.NameDelegate();
      _vmf_delegate4.setCaller(this);
    }

    return _vmf_delegate4.nameWithLower();
  }

  public java.lang.String nameWithUpper() {

    if(_vmf_delegate4==null) {
      _vmf_delegate4 = new eu.mihosoft.vmf.vmftext.grammar.NameDelegate();
      _vmf_delegate4.setCaller(this);
    }

    return _vmf_delegate4.nameWithUpper();
  }

  public java.lang.String superInterfacesString() {

    if(_vmf_delegate5==null) {
      _vmf_delegate5 = new eu.mihosoft.vmf.vmftext.grammar.StringUtilDelegate();
      _vmf_delegate5.setCaller(this);
    }

    return _vmf_delegate5.superInterfacesString();
  }


  // --------------------------------------------------------------------
  // --- Utility methods
  // --------------------------------------------------------------------

  @Override
  public void addPropertyChangeListener(PropertyChangeListener l) {
      _vmf_getPropertyChanges().addPropertyChangeListener(l);
  }
  @Override
  public void removePropertyChangeListener(PropertyChangeListener l) {
      _vmf_getPropertyChanges().removePropertyChangeListener(l);

      if(_vmf_getPropertyChanges().getPropertyChangeListeners().length==0) {
          propertyChanges = null;
      }
  }

  private PropertyChangeSupport _vmf_getPropertyChanges() {

      if(propertyChanges==null) {
          propertyChanges = new PropertyChangeSupport(this);
      }

      return propertyChanges;
  }

  private boolean _vmf_hasListeners() {
      return propertyChanges!=null;
  }

  private void _vmf_firePropertyChangeIfListenersArePresent(
    String propertyName, Object oldValue, Object newValue) {
      if(_vmf_hasListeners()) {
          _vmf_getPropertyChanges().
                  firePropertyChange(propertyName, oldValue, newValue);
      }
  }

  // --------------------------------------------------------------------
  // --- Public VMF API
  // --------------------------------------------------------------------

 private eu.mihosoft.vmf.runtime.core.VMF vmf;

  @Override
  public eu.mihosoft.vmf.runtime.core.VMF vmf() {
    if(vmf==null) {
      vmf = new eu.mihosoft.vmf.runtime.core.VMF() {
        public eu.mihosoft.vmf.runtime.core.Content content() {
          return new eu.mihosoft.vmf.runtime.core.Content() {
            public eu.mihosoft.vmf.runtime.core.VIterator iterator() {
              return eu.mihosoft.vmf.runtime.core.VIterator.of(RuleClassImpl.this);
            }
            public java.util.stream.Stream stream() {
              return eu.mihosoft.vmf.runtime.core.VIterator.of(RuleClassImpl.this).asStream();
            }

            public eu.mihosoft.vmf.runtime.core.VIterator iterator(eu.mihosoft.vmf.runtime.core.VIterator.IterationStrategy strategy) {
              return eu.mihosoft.vmf.runtime.core.VIterator.of(RuleClassImpl.this, strategy);
            }
            public java.util.stream.Stream stream(eu.mihosoft.vmf.runtime.core.VIterator.IterationStrategy strategy) {
              return eu.mihosoft.vmf.runtime.core.VIterator.of(RuleClassImpl.this, strategy).asStream();
            }
            public  java.util.stream.Stream stream(Class type) {
              return stream().filter(e->type.isAssignableFrom(e.getClass())).map(e->(T)e);
            }
            public  java.util.stream.Stream stream(Class type, eu.mihosoft.vmf.runtime.core.VIterator.IterationStrategy strategy) {
              return stream(strategy).filter(e->type.isAssignableFrom(e.getClass())).map(e->(T)e);
            }
            public VList referencedBy() {
              return _vmf_referencedBy().asUnmodifiable();
            }
            public VList references() {
              return _vmf_references().asUnmodifiable();
            }


            @Override
            public RuleClass deepCopy() {
               java.util.IdentityHashMap identityMap =
               new java.util.IdentityHashMap<>();
               return _vmf_deepCopy(identityMap);
            }

            @Override
            public RuleClass shallowCopy() {
              return RuleClassImpl.
                this._vmf_shallowCopy(new java.util.IdentityHashMap<>());
              }
            };
          }

          private eu.mihosoft.vmf.runtime.core.internal.ChangesImpl changes;

          public eu.mihosoft.vmf.runtime.core.Changes changes() {
            if (changes==null) {
              changes = new eu.mihosoft.vmf.runtime.core.internal.ChangesImpl();
              changes.setModel(RuleClassImpl.this);
            }

            return changes;
          }

          private eu.mihosoft.vmf.runtime.core.internal.ReflectImpl reflect;

          public eu.mihosoft.vmf.runtime.core.Reflect reflect() {
            if (reflect==null) {
              reflect = new eu.mihosoft.vmf.runtime.core.internal.ReflectImpl();
              reflect.setModel(RuleClassImpl.this);
            }

            return reflect;
          }


        }; // end vmf
      } // end if null

      return vmf;
  }

  private ReadOnlyRuleClass readOnlyInstance;

  @Override
  public ReadOnlyRuleClass asReadOnly() {

    if(readOnlyInstance==null) {
      readOnlyInstance = new eu.mihosoft.vmf.vmftext.grammar.impl.
        ReadOnlyRuleClassImpl(this);
    }

    return readOnlyInstance;
  }

  // --------------------------------------------------------------------
  // --- Reflection methods
  // --------------------------------------------------------------------

  // type id for improved reflection performance
  public static final int _VMF_TYPE_ID = 28;

  @Override
  public int _vmf_getTypeId() {
    return _VMF_TYPE_ID;
  }


  static final String[] _VMF_PROPERTY_NAMES = {
    "childClasses",
    "codeRange",
    "customProperties",
    "customRuleAnnotations",
    "delegationMethods",
    "model",
    "name",
    "properties",
    "root",
    "superClass",
    "superInterfaces"
  };

  static final String[] _VMF_PROPERTY_TYPE_NAMES = {
    "eu.mihosoft.vcollections.VList", // type id -2
    "eu.mihosoft.vmf.vmftext.grammar.CodeRange", // type id 8
    "eu.mihosoft.vcollections.VList", // type id -2
    "eu.mihosoft.vcollections.VList", // type id -2
    "eu.mihosoft.vcollections.VList", // type id -2
    "eu.mihosoft.vmf.vmftext.grammar.GrammarModel", // type id 14
    "java.lang.String", // type id -1
    "eu.mihosoft.vcollections.VList", // type id -2
    "boolean", // type id -1
    "eu.mihosoft.vmf.vmftext.grammar.RuleClass", // type id 28
    "eu.mihosoft.vcollections.VList"  // type id -2
  };

  static final int[] _VMF_PROPERTY_TYPES = {
       -2, // type eu.mihosoft.vcollections.VList
        8, // type eu.mihosoft.vmf.vmftext.grammar.CodeRange
       -2, // type eu.mihosoft.vcollections.VList
       -2, // type eu.mihosoft.vcollections.VList
       -2, // type eu.mihosoft.vcollections.VList
       14, // type eu.mihosoft.vmf.vmftext.grammar.GrammarModel
       -1, // type java.lang.String
       -2, // type eu.mihosoft.vcollections.VList
       -1, // type boolean
       28, // type eu.mihosoft.vmf.vmftext.grammar.RuleClass
       -2  // type eu.mihosoft.vcollections.VList
  };


  /**
   * - indices of model objects as properties
   * - parents, i.e., containers are skipped
   * - only indices of reference properties and contained elements, i.e.,
   *   children are listed here
   */
  static final int[] _VMF_PROPERTIES_WITH_MODEL_TYPES_INDICES = {
        1, // type eu.mihosoft.vmf.vmftext.grammar.CodeRange
        5, // type eu.mihosoft.vmf.vmftext.grammar.GrammarModel
  };

  /**
   * - indices of lists that contain model objects as elements
   */
  static final int[] _VMF_PROPERTIES_WITH_MODEL_ELEMENT_TYPES_INDICES = {
        0, // type eu.mihosoft.vcollections.VList
        2, // type eu.mihosoft.vcollections.VList
        3, // type eu.mihosoft.vcollections.VList
        4, // type eu.mihosoft.vcollections.VList
        7, // type eu.mihosoft.vcollections.VList
  };

  /**
   * - indices of model objects as properties and model objects as
   *   elements of lists
   * - parents, i.e., containers are skipped
   * - only indices of reference properties and contained elements, i.e.,
   *   children are listed here
   */
  static final int[] _VMF_PROPERTIES_WITH_MODEL_TYPE_OR_ELEMENT_TYPES_INDICES = {
        0, // type eu.mihosoft.vcollections.VList
        1, // type eu.mihosoft.vmf.vmftext.grammar.CodeRange
        2, // type eu.mihosoft.vcollections.VList
        3, // type eu.mihosoft.vcollections.VList
        4, // type eu.mihosoft.vcollections.VList
        5, // type eu.mihosoft.vmf.vmftext.grammar.GrammarModel
        7, // type eu.mihosoft.vcollections.VList
  };

  /**
   * - indices of model children
   * - parents, i.e., containers and pure references are skipped
   * - only indices of contained elements, i.e.,
   *   children are listed here
   */
  static final int[] _VMF_CHILDREN_INDICES = {
        0, // type eu.mihosoft.vcollections.VList
        2, // type eu.mihosoft.vcollections.VList
        3, // type eu.mihosoft.vcollections.VList
        4, // type eu.mihosoft.vcollections.VList
        5, // type eu.mihosoft.vmf.vmftext.grammar.GrammarModel
        7, // type eu.mihosoft.vcollections.VList
  };

  @Override
  public String[] _vmf_getPropertyNames() {
    return _VMF_PROPERTY_NAMES;
  }

  @Override
  public int[] _vmf_getPropertyTypes() {
    return _VMF_PROPERTY_TYPES;
  }

  @Override
  public String[] _vmf_getPropertyTypeNames() {
    return _VMF_PROPERTY_TYPE_NAMES;
  }

  @Override
  public int[] _vmf_getIndicesOfPropertiesWithModelTypes() {
    return _VMF_PROPERTIES_WITH_MODEL_TYPES_INDICES;
  }

  @Override
  public int[] _vmf_getIndicesOfPropertiesWithModelElementTypes() {
    return _VMF_PROPERTIES_WITH_MODEL_ELEMENT_TYPES_INDICES;
  }

  @Override
  public int[] _vmf_getIndicesOfPropertiesWithModelTypeOrElementTypes() {
    return _VMF_PROPERTIES_WITH_MODEL_TYPE_OR_ELEMENT_TYPES_INDICES;
  }

  @Override
  public int[] _vmf_getChildrenIndices() {
    return _VMF_CHILDREN_INDICES;
  }

  @Override
  public Object _vmf_getPropertyValueById(int propertyId) {

    switch(propertyId) {
      case 0:
        // TODO check whether we can prevent lazy initialized properties from
        //      being initialized just for iterating the object graph
        return getChildClasses();
      case 1:
        // TODO check whether we can prevent lazy initialized properties from
        //      being initialized just for iterating the object graph
        return getCodeRange();
      case 2:
        // TODO check whether we can prevent lazy initialized properties from
        //      being initialized just for iterating the object graph
        return getCustomProperties();
      case 3:
        // TODO check whether we can prevent lazy initialized properties from
        //      being initialized just for iterating the object graph
        return getCustomRuleAnnotations();
      case 4:
        // TODO check whether we can prevent lazy initialized properties from
        //      being initialized just for iterating the object graph
        return getDelegationMethods();
      case 5:
        // TODO check whether we can prevent lazy initialized properties from
        //      being initialized just for iterating the object graph
        return getModel();
      case 6:
        // TODO check whether we can prevent lazy initialized properties from
        //      being initialized just for iterating the object graph
        return getName();
      case 7:
        // TODO check whether we can prevent lazy initialized properties from
        //      being initialized just for iterating the object graph
        return getProperties();
      case 8:
        // TODO check whether we can prevent lazy initialized properties from
        //      being initialized just for iterating the object graph
        return isRoot();
      case 9:
        // TODO check whether we can prevent lazy initialized properties from
        //      being initialized just for iterating the object graph
        return getSuperClass();
      case 10:
        // TODO check whether we can prevent lazy initialized properties from
        //      being initialized just for iterating the object graph
        return getSuperInterfaces();
    }

    return null;
  }

  @Override
  public int _vmf_getPropertyIdByName(String propertyName) {
    switch(propertyName) {
      case "childClasses":
        return 0;
      case "codeRange":
        return 1;
      case "customProperties":
        return 2;
      case "customRuleAnnotations":
        return 3;
      case "delegationMethods":
        return 4;
      case "model":
        return 5;
      case "name":
        return 6;
      case "properties":
        return 7;
      case "root":
        return 8;
      case "superClass":
        return 9;
      case "superInterfaces":
        return 10;
      default:
        return -1;
    } // end switch
  }

  @Override
  public void _vmf_setPropertyValueById(int propertyId, Object value) {
    switch(propertyId) {
      case 1: // normal property (no collection and no containment)
        setCodeRange((eu.mihosoft.vmf.vmftext.grammar.CodeRange)value);
        break;
      case 5: // normal property (no collection and no containment)
        setModel((eu.mihosoft.vmf.vmftext.grammar.GrammarModel)value);
        break;
      case 6: // normal property (no collection and no containment)
        setName((java.lang.String)value);
        break;
      case 8: // normal property (no collection and no containment)
        setRoot((boolean)value);
        break;
      case 10: // collection property
        getSuperInterfaces().clear();
        getSuperInterfaces().addAll((eu.mihosoft.vcollections.VList)value);
        break;
      default:
            throw new RuntimeException("Cannot set property with id="+propertyId +": property is not writable.");
    } // end switch
  }

  @Override
  public Object _vmf_getDefaultValueById(int propertyId) {

    switch(propertyId) {
      case 0:
        Object __vmf_default_value_tmpChildClasses = _VMF_DEFAULT_VALUES[0];
        if(__vmf_default_value_tmpChildClasses==null) {
            return null;
        } else {
            return __vmf_default_value_tmpChildClasses;
        }

      case 1:
        Object __vmf_default_value_tmpCodeRange = _VMF_DEFAULT_VALUES[0];
        if(__vmf_default_value_tmpCodeRange==null) {
            return null;
        } else {
            return __vmf_default_value_tmpCodeRange;
        }

      case 2:
        Object __vmf_default_value_tmpCustomProperties = _VMF_DEFAULT_VALUES[1];
        if(__vmf_default_value_tmpCustomProperties==null) {
            return null;
        } else {
            return __vmf_default_value_tmpCustomProperties;
        }

      case 3:
        Object __vmf_default_value_tmpCustomRuleAnnotations = _VMF_DEFAULT_VALUES[2];
        if(__vmf_default_value_tmpCustomRuleAnnotations==null) {
            return null;
        } else {
            return __vmf_default_value_tmpCustomRuleAnnotations;
        }

      case 4:
        Object __vmf_default_value_tmpDelegationMethods = _VMF_DEFAULT_VALUES[3];
        if(__vmf_default_value_tmpDelegationMethods==null) {
            return null;
        } else {
            return __vmf_default_value_tmpDelegationMethods;
        }

      case 5:
        Object __vmf_default_value_tmpModel = _VMF_DEFAULT_VALUES[4];
        if(__vmf_default_value_tmpModel==null) {
            return null;
        } else {
            return __vmf_default_value_tmpModel;
        }

      case 6:
        Object __vmf_default_value_tmpName = _VMF_DEFAULT_VALUES[0];
        if(__vmf_default_value_tmpName==null) {
            return null;
        } else {
            return __vmf_default_value_tmpName;
        }

      case 7:
        Object __vmf_default_value_tmpProperties = _VMF_DEFAULT_VALUES[5];
        if(__vmf_default_value_tmpProperties==null) {
            return null;
        } else {
            return __vmf_default_value_tmpProperties;
        }

      case 8:
        Object __vmf_default_value_tmpRoot = _VMF_DEFAULT_VALUES[6];
        if(__vmf_default_value_tmpRoot==null) {
            return
            false;
        } else {
            return __vmf_default_value_tmpRoot;
        }    

      case 9:
        Object __vmf_default_value_tmpSuperClass = _VMF_DEFAULT_VALUES[7];
        if(__vmf_default_value_tmpSuperClass==null) {
            return null;
        } else {
            return __vmf_default_value_tmpSuperClass;
        }

      case 10:
        Object __vmf_default_value_tmpSuperInterfaces = _VMF_DEFAULT_VALUES[8];
        if(__vmf_default_value_tmpSuperInterfaces==null) {
            return null;
        } else {
            return __vmf_default_value_tmpSuperInterfaces;
        }

    } // end switch

    return null;
  }

  @Override
  public void _vmf_setDefaultValueById(int propertyId, Object defaultValue) {

    // property childClasses
    if(propertyId == 0) { 
      throw new RuntimeException("Cannot set default value for property 'childClasses' with id="+propertyId +": property is a containment property and not writable.");
    }
    // property customProperties
    if(propertyId == 2) { 
      throw new RuntimeException("Cannot set default value for property 'customProperties' with id="+propertyId +": property is a containment property and not writable.");
    }
    // property customRuleAnnotations
    if(propertyId == 3) { 
      throw new RuntimeException("Cannot set default value for property 'customRuleAnnotations' with id="+propertyId +": property is a containment property and not writable.");
    }
    // property delegationMethods
    if(propertyId == 4) { 
      throw new RuntimeException("Cannot set default value for property 'delegationMethods' with id="+propertyId +": property is a containment property and not writable.");
    }
    // property model
    if(propertyId == 5) { 
      throw new RuntimeException("Cannot set default value for property 'model' with id="+propertyId +": property is a containment property and not writable.");
    }
    // property properties
    if(propertyId == 7) { 
      throw new RuntimeException("Cannot set default value for property 'properties' with id="+propertyId +": property is a containment property and not writable.");
    }
    // property superClass
    if(propertyId == 9) { 
      throw new RuntimeException("Cannot set default value for property 'superClass' with id="+propertyId +": property is a containment property and not writable.");
    }

    // if the value was previously unset then we need to update
    // the value to the new default value
    boolean isSetBeforeDefaultUpdate = _vmf_isSetById(propertyId);
    _VMF_DEFAULT_VALUES[propertyId] = defaultValue;
    if(!isSetBeforeDefaultUpdate) {
      _vmf_unsetById(propertyId);
    }
  }

  @Override
  public boolean _vmf_isSetById(int propertyId) {
    return !java.util.Objects.equals(_vmf_getDefaultValueById(propertyId), _vmf_getPropertyValueById(propertyId));
  }

  @Override
  public void _vmf_unsetById(int propertyId) {
    _vmf_setPropertyValueById(propertyId, _vmf_getDefaultValueById(propertyId));
  }

  final Object[] _VMF_DEFAULT_VALUES = {
    null, // type childClasses (containment type, no defaut value possible)  
    null, // type codeRange   
    null, // type customProperties (containment type, no defaut value possible)  
    null, // type customRuleAnnotations (containment type, no defaut value possible)  
    null, // type delegationMethods (containment type, no defaut value possible)  
    null, // type model (containment type, no defaut value possible)  
    null, // type name   
    null, // type properties (containment type, no defaut value possible)  
    null, // type root   
    null, // type superClass (containment type, no defaut value possible)  
    null  // type superInterfaces   
  };

  // --------------------------------------------------------------------
  // --- Id related methods
  // --------------------------------------------------------------------

  // id management is currently not part of VMF (TODO how should we support this?)

  // --------------------------------------------------------------------
  // --- Reference methods
  // --------------------------------------------------------------------

  @Override
  public VList _vmf_referencedBy() { return this.referencedBy;}
  @Override
  public VList _vmf_references() { return this.references;}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy