CommonScopeProvider.java

/**
 * Copyright (c) 2004-2025 Carnegie Mellon University and others. (see Contributors file).
 * All Rights Reserved.
 * 
 * NO WARRANTY. ALL MATERIAL IS FURNISHED ON AN "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY
 * KIND, EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE
 * OR MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF THE MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT
 * MAKE ANY WARRANTY OF ANY KIND WITH RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.
 * 
 * This program and the accompanying materials are made available under the terms of the Eclipse Public License 2.0
 * which is available at https://www.eclipse.org/legal/epl-2.0/
 * SPDX-License-Identifier: EPL-2.0
 * 
 * Created, in part, with funding and support from the United States Government. (see Acknowledgments file).
 * 
 * This program includes and/or can make use of certain third party source code, object code, documentation and other
 * files ("Third Party Software"). The Third Party Software that is used by this program is dependent upon your system
 * configuration. By using this program, You agree to comply with any and all relevant Third Party Software terms and
 * conditions contained in any such Third Party Software or separate license file distributed with such Third Party
 * Software. The parties who own the Third Party Software ("Third Party Licensors") are intended third party benefici-
 * aries to this license with respect to the terms applicable to their Third Party Software. Third Party Software li-
 * censes only apply to the Third Party Software and not any other portion of this program or this program as a whole.
 */
package org.osate.alisa.common.scoping;

import com.google.common.collect.Iterables;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.xtext.naming.QualifiedName;
import org.eclipse.xtext.resource.EObjectDescription;
import org.eclipse.xtext.resource.IEObjectDescription;
import org.eclipse.xtext.scoping.IScope;
import org.eclipse.xtext.scoping.Scopes;
import org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider;
import org.eclipse.xtext.scoping.impl.SimpleScope;
import org.eclipse.xtext.util.SimpleAttributeResolver;
import org.eclipse.xtext.xbase.lib.CollectionLiterals;
import org.eclipse.xtext.xbase.lib.Functions.Function1;
import org.eclipse.xtext.xbase.lib.IterableExtensions;
import org.osate.aadl2.Aadl2Package;
import org.osate.aadl2.AbstractFeature;
import org.osate.aadl2.AbstractFeatureClassifier;
import org.osate.aadl2.Classifier;
import org.osate.aadl2.ComponentClassifier;
import org.osate.aadl2.ComponentPrototype;
import org.osate.aadl2.EnumerationLiteral;
import org.osate.aadl2.Feature;
import org.osate.aadl2.FeatureClassifier;
import org.osate.aadl2.FeatureGroup;
import org.osate.aadl2.FeatureGroupPrototype;
import org.osate.aadl2.FeatureGroupType;
import org.osate.aadl2.FeatureType;
import org.osate.aadl2.NamedElement;
import org.osate.aadl2.Subcomponent;
import org.osate.aadl2.SubcomponentType;
import org.osate.aadl2.UnitLiteral;
import org.osate.aadl2.UnitsType;
import org.osate.aadl2.modelsupport.scoping.Aadl2GlobalScopeUtil;
import org.osate.aadl2.modelsupport.util.AadlUtil;
import org.osate.alisa.common.common.AModelReference;
import org.osate.xtext.aadl2.properties.scoping.PropertiesScopeProvider;

@SuppressWarnings("all")
public class CommonScopeProvider extends AbstractDeclarativeScopeProvider {
  public SimpleScope scopeFor(final Iterable<? extends EObject> elements) {
    Iterable<IEObjectDescription> _scopedElementsFor = Scopes.<EObject>scopedElementsFor(elements, QualifiedName.<EObject>wrapper(SimpleAttributeResolver.NAME_RESOLVER));
    return new SimpleScope(IScope.NULLSCOPE, _scopedElementsFor, false);
  }

  public IScope scope_UnitLiteral(final EObject context, final EReference reference) {
    IScope _xblockexpression = null;
    {
      final Collection<UnitLiteral> units = this.getUnitLiterals(context);
      IScope _xifexpression = null;
      boolean _isEmpty = units.isEmpty();
      boolean _not = (!_isEmpty);
      if (_not) {
        _xifexpression = this.scopeFor(units);
      } else {
        _xifexpression = IScope.NULLSCOPE;
      }
      _xblockexpression = _xifexpression;
    }
    return _xblockexpression;
  }

  private static final EClass UNITS_TYPE = Aadl2Package.eINSTANCE.getUnitsType();

  private Collection<UnitLiteral> getUnitLiterals(final EObject context) {
    final Collection<UnitLiteral> result = new ArrayList<UnitLiteral>();
    Iterable<IEObjectDescription> _allEObjectDescriptions = Aadl2GlobalScopeUtil.getAllEObjectDescriptions(context, CommonScopeProvider.UNITS_TYPE);
    for (final IEObjectDescription desc : _allEObjectDescriptions) {
      {
        EObject _resolve = EcoreUtil.resolve(desc.getEObjectOrProxy(), context);
        final UnitsType unitsType = ((UnitsType) _resolve);
        final Function1<EnumerationLiteral, Boolean> _function = (EnumerationLiteral lit) -> {
          return Boolean.valueOf(result.add(((UnitLiteral) lit)));
        };
        IterableExtensions.<EnumerationLiteral>forall(unitsType.getOwnedLiterals(), _function);
      }
    }
    return result;
  }

  public IScope scope_NumberType_referencedUnitsType(final EObject context, final EReference reference) {
    return this.propertySetMemberScope(context, reference);
  }

  public IScope scope_TypeRef_ref(final EObject context, final EReference reference) {
    return this.propertySetMemberScope(context, reference);
  }

  public IScope scope_Property(final EObject context, final EReference reference) {
    return this.propertySetMemberScope(context, reference);
  }

  public IScope scope_APropertyReference_property(final EObject context, final EReference reference) {
    return this.propertySetMemberScope(context, reference);
  }

  public IScope scope_ComponentImplementation(final EObject context, final EReference reference) {
    final Function1<IEObjectDescription, IEObjectDescription> _function = (IEObjectDescription it) -> {
      return this.convertImplName(it);
    };
    Iterable<IEObjectDescription> _map = IterableExtensions.<IEObjectDescription, IEObjectDescription>map(this.delegateGetScope(context, reference).getAllElements(), _function);
    return new SimpleScope(_map, false);
  }

  public IScope scope_ComponentClassifier(final EObject context, final EReference reference) {
    final Function1<IEObjectDescription, IEObjectDescription> _function = (IEObjectDescription it) -> {
      IEObjectDescription _xifexpression = null;
      boolean _isSuperTypeOf = Aadl2Package.eINSTANCE.getComponentImplementation().isSuperTypeOf(it.getEObjectOrProxy().eClass());
      if (_isSuperTypeOf) {
        _xifexpression = this.convertImplName(it);
      } else {
        _xifexpression = EObjectDescription.create(it.getName().toString("::"), it.getEObjectOrProxy());
      }
      return _xifexpression;
    };
    Iterable<IEObjectDescription> _map = IterableExtensions.<IEObjectDescription, IEObjectDescription>map(this.delegateGetScope(context, reference).getAllElements(), _function);
    return new SimpleScope(_map, false);
  }

  private SimpleScope propertySetMemberScope(final EObject context, final EReference reference) {
    final Function1<IEObjectDescription, Iterable<IEObjectDescription>> _function = (IEObjectDescription it) -> {
      IEObjectDescription _create = EObjectDescription.create(it.getName().toString("::"), it.getEObjectOrProxy());
      List<IEObjectDescription> _xifexpression = null;
      boolean _isPredeclaredPropertySet = AadlUtil.isPredeclaredPropertySet(it.getName().getFirstSegment());
      if (_isPredeclaredPropertySet) {
        IEObjectDescription _create_1 = EObjectDescription.create(it.getName().getLastSegment(), it.getEObjectOrProxy());
        _xifexpression = Collections.<IEObjectDescription>unmodifiableList(CollectionLiterals.<IEObjectDescription>newArrayList(_create_1));
      } else {
        _xifexpression = CollectionLiterals.<IEObjectDescription>emptyList();
      }
      return Iterables.<IEObjectDescription>concat(Collections.<IEObjectDescription>unmodifiableList(CollectionLiterals.<IEObjectDescription>newArrayList(_create)), _xifexpression);
    };
    Iterable<IEObjectDescription> _flatten = Iterables.<IEObjectDescription>concat(IterableExtensions.<IEObjectDescription, Iterable<IEObjectDescription>>map(this.delegateGetScope(context, reference).getAllElements(), _function));
    return new SimpleScope(_flatten, false);
  }

  private IEObjectDescription convertImplName(final IEObjectDescription description) {
    IEObjectDescription _xblockexpression = null;
    {
      final String[] implName = description.getName().getLastSegment().split("\\.");
      String _string = description.getName().skipLast(1).toString("::");
      String _plus = (_string + "::");
      String _get = implName[0];
      final String typename = (_plus + _get);
      QualifiedName _xifexpression = null;
      int _length = implName.length;
      boolean _greaterThan = (_length > 1);
      if (_greaterThan) {
        _xifexpression = QualifiedName.create(typename, implName[1]);
      } else {
        _xifexpression = QualifiedName.create(typename);
      }
      final QualifiedName newName = _xifexpression;
      _xblockexpression = EObjectDescription.create(newName, description.getEObjectOrProxy());
    }
    return _xblockexpression;
  }

  public IScope scope_AModelReference_modelElement(final EObject context, final EReference reference) {
    IEObjectDescription _create = EObjectDescription.create("this", context);
    return new SimpleScope(Collections.<IEObjectDescription>unmodifiableList(CollectionLiterals.<IEObjectDescription>newArrayList(_create)));
  }

  public EObject getAModelReferenceContext(final AModelReference amr) {
    EObject context = amr.eContainer();
    while ((context instanceof AModelReference)) {
      context = ((AModelReference)context).eContainer();
    }
    return context;
  }

  public IScope scope_AModelReference_modelElement(final AModelReference context, final EReference reference) {
    IScope _xifexpression = null;
    AModelReference _prev = context.getPrev();
    boolean _tripleEquals = (_prev == null);
    if (_tripleEquals) {
      _xifexpression = this.scope_AModelReference_modelElement(this.getAModelReferenceContext(context), reference);
    } else {
      SimpleScope _xblockexpression = null;
      {
        final AModelReference prev = context.getPrev();
        final NamedElement prevElement = prev.getModelElement();
        Classifier _switchResult = null;
        boolean _matched = false;
        if (prevElement instanceof Classifier) {
          _matched=true;
          _switchResult = ((Classifier)prevElement);
        }
        if (!_matched) {
          if (prevElement instanceof AbstractFeature) {
            _matched=true;
            ComponentClassifier _switchResult_1 = null;
            AbstractFeatureClassifier _abstractFeatureClassifier = ((AbstractFeature)prevElement).getAbstractFeatureClassifier();
            final AbstractFeatureClassifier featureClassifier = _abstractFeatureClassifier;
            boolean _matched_1 = false;
            if (featureClassifier instanceof ComponentClassifier) {
              _matched_1=true;
              _switchResult_1 = ((ComponentClassifier)featureClassifier);
            }
            if (!_matched_1) {
              if (featureClassifier instanceof ComponentPrototype) {
                _matched_1=true;
                _switchResult_1 = ((ComponentPrototype)featureClassifier).getConstrainingClassifier();
              }
            }
            if (!_matched_1) {
              _switchResult_1 = ((AbstractFeature)prevElement).getFeaturePrototype().getConstrainingClassifier();
            }
            _switchResult = _switchResult_1;
          }
        }
        if (!_matched) {
          if (prevElement instanceof FeatureGroup) {
            _matched=true;
            FeatureGroupType _switchResult_1 = null;
            FeatureType _featureType = ((FeatureGroup)prevElement).getFeatureType();
            final FeatureType featureType = _featureType;
            boolean _matched_1 = false;
            if (featureType instanceof FeatureGroupType) {
              _matched_1=true;
              _switchResult_1 = ((FeatureGroupType)featureType);
            }
            if (!_matched_1) {
              if (featureType instanceof FeatureGroupPrototype) {
                _matched_1=true;
                _switchResult_1 = ((FeatureGroupPrototype)featureType).getConstrainingFeatureGroupType();
              }
            }
            _switchResult = _switchResult_1;
          }
        }
        if (!_matched) {
          if (prevElement instanceof Feature) {
            _matched=true;
            ComponentClassifier _switchResult_1 = null;
            FeatureClassifier _featureClassifier = ((Feature)prevElement).getFeatureClassifier();
            final FeatureClassifier featureClassifier = _featureClassifier;
            boolean _matched_1 = false;
            if (featureClassifier instanceof ComponentClassifier) {
              _matched_1=true;
              _switchResult_1 = ((ComponentClassifier)featureClassifier);
            }
            if (!_matched_1) {
              if (featureClassifier instanceof ComponentPrototype) {
                _matched_1=true;
                _switchResult_1 = ((ComponentPrototype)featureClassifier).getConstrainingClassifier();
              }
            }
            _switchResult = _switchResult_1;
          }
        }
        if (!_matched) {
          if (prevElement instanceof Subcomponent) {
            _matched=true;
            ComponentClassifier _switchResult_1 = null;
            SubcomponentType _subcomponentType = ((Subcomponent)prevElement).getSubcomponentType();
            final SubcomponentType subcomponentType = _subcomponentType;
            boolean _matched_1 = false;
            if (subcomponentType instanceof ComponentClassifier) {
              _matched_1=true;
              _switchResult_1 = ((ComponentClassifier)subcomponentType);
            }
            if (!_matched_1) {
              if (subcomponentType instanceof ComponentPrototype) {
                _matched_1=true;
                _switchResult_1 = ((ComponentPrototype)subcomponentType).getConstrainingClassifier();
              }
            }
            _switchResult = _switchResult_1;
          }
        }
        ArrayList<NamedElement> _allMembers = null;
        if (_switchResult!=null) {
          Classifier _switchResult_1 = null;
          boolean _matched_1 = false;
          if (prevElement instanceof Classifier) {
            _matched_1=true;
            _switchResult_1 = ((Classifier)prevElement);
          }
          if (!_matched_1) {
            if (prevElement instanceof AbstractFeature) {
              _matched_1=true;
              ComponentClassifier _switchResult_2 = null;
              AbstractFeatureClassifier _abstractFeatureClassifier = ((AbstractFeature)prevElement).getAbstractFeatureClassifier();
              final AbstractFeatureClassifier featureClassifier = _abstractFeatureClassifier;
              boolean _matched_2 = false;
              if (featureClassifier instanceof ComponentClassifier) {
                _matched_2=true;
                _switchResult_2 = ((ComponentClassifier)featureClassifier);
              }
              if (!_matched_2) {
                if (featureClassifier instanceof ComponentPrototype) {
                  _matched_2=true;
                  _switchResult_2 = ((ComponentPrototype)featureClassifier).getConstrainingClassifier();
                }
              }
              if (!_matched_2) {
                _switchResult_2 = ((AbstractFeature)prevElement).getFeaturePrototype().getConstrainingClassifier();
              }
              _switchResult_1 = _switchResult_2;
            }
          }
          if (!_matched_1) {
            if (prevElement instanceof FeatureGroup) {
              _matched_1=true;
              FeatureGroupType _switchResult_2 = null;
              FeatureType _featureType = ((FeatureGroup)prevElement).getFeatureType();
              final FeatureType featureType = _featureType;
              boolean _matched_2 = false;
              if (featureType instanceof FeatureGroupType) {
                _matched_2=true;
                _switchResult_2 = ((FeatureGroupType)featureType);
              }
              if (!_matched_2) {
                if (featureType instanceof FeatureGroupPrototype) {
                  _matched_2=true;
                  _switchResult_2 = ((FeatureGroupPrototype)featureType).getConstrainingFeatureGroupType();
                }
              }
              _switchResult_1 = _switchResult_2;
            }
          }
          if (!_matched_1) {
            if (prevElement instanceof Feature) {
              _matched_1=true;
              ComponentClassifier _switchResult_2 = null;
              FeatureClassifier _featureClassifier = ((Feature)prevElement).getFeatureClassifier();
              final FeatureClassifier featureClassifier = _featureClassifier;
              boolean _matched_2 = false;
              if (featureClassifier instanceof ComponentClassifier) {
                _matched_2=true;
                _switchResult_2 = ((ComponentClassifier)featureClassifier);
              }
              if (!_matched_2) {
                if (featureClassifier instanceof ComponentPrototype) {
                  _matched_2=true;
                  _switchResult_2 = ((ComponentPrototype)featureClassifier).getConstrainingClassifier();
                }
              }
              _switchResult_1 = _switchResult_2;
            }
          }
          if (!_matched_1) {
            if (prevElement instanceof Subcomponent) {
              _matched_1=true;
              ComponentClassifier _switchResult_2 = null;
              SubcomponentType _subcomponentType = ((Subcomponent)prevElement).getSubcomponentType();
              final SubcomponentType subcomponentType = _subcomponentType;
              boolean _matched_2 = false;
              if (subcomponentType instanceof ComponentClassifier) {
                _matched_2=true;
                _switchResult_2 = ((ComponentClassifier)subcomponentType);
              }
              if (!_matched_2) {
                if (subcomponentType instanceof ComponentPrototype) {
                  _matched_2=true;
                  _switchResult_2 = ((ComponentPrototype)subcomponentType).getConstrainingClassifier();
                }
              }
              _switchResult_1 = _switchResult_2;
            }
          }
          _allMembers=PropertiesScopeProvider.allMembers(_switchResult);
        }
        SimpleScope _scopeFor = null;
        if (_allMembers!=null) {
          _scopeFor=this.scopeFor(_allMembers);
        }
        _xblockexpression = _scopeFor;
      }
      _xifexpression = _xblockexpression;
    }
    return _xifexpression;
  }
}