ErrorModelProposalProvider.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.xtext.aadl2.errormodel.ui.contentassist;

import com.google.common.base.Objects;
import com.google.common.base.Predicate;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.xtext.AbstractElement;
import org.eclipse.xtext.Assignment;
import org.eclipse.xtext.CrossReference;
import org.eclipse.xtext.EcoreUtil2;
import org.eclipse.xtext.resource.IEObjectDescription;
import org.eclipse.xtext.ui.editor.contentassist.ContentAssistContext;
import org.eclipse.xtext.ui.editor.contentassist.ICompletionProposalAcceptor;
import org.eclipse.xtext.xbase.lib.Functions.Function1;
import org.eclipse.xtext.xbase.lib.IterableExtensions;
import org.osate.aadl2.NamedElement;
import org.osate.xtext.aadl2.errormodel.errorModel.ConditionElement;
import org.osate.xtext.aadl2.errormodel.errorModel.ErrorBehaviorTransition;
import org.osate.xtext.aadl2.errormodel.errorModel.ErrorEvent;
import org.osate.xtext.aadl2.errormodel.errorModel.ErrorModelLibrary;
import org.osate.xtext.aadl2.errormodel.errorModel.ErrorPath;
import org.osate.xtext.aadl2.errormodel.errorModel.ErrorPropagation;
import org.osate.xtext.aadl2.errormodel.errorModel.ErrorSink;
import org.osate.xtext.aadl2.errormodel.errorModel.ErrorSource;
import org.osate.xtext.aadl2.errormodel.errorModel.ErrorType;
import org.osate.xtext.aadl2.errormodel.errorModel.ErrorTypes;
import org.osate.xtext.aadl2.errormodel.errorModel.EventOrPropagation;
import org.osate.xtext.aadl2.errormodel.errorModel.TypeSet;
import org.osate.xtext.aadl2.errormodel.errorModel.TypeToken;
import org.osate.xtext.aadl2.errormodel.util.EMV2Util;

/**
 * see http://www.eclipse.org/Xtext/documentation/latest/xtext.html#contentAssist on how to customize content assistant
 */
@SuppressWarnings("all")
public class ErrorModelProposalProvider extends AbstractErrorModelProposalProvider {
  @Override
  public void completeErrorModelLibrary_Extends(final EObject model, final Assignment assignment, final ContentAssistContext context, final ICompletionProposalAcceptor acceptor) {
    AbstractElement _terminal = assignment.getTerminal();
    final Predicate<IEObjectDescription> _function = (IEObjectDescription it) -> {
      EObject _resolve = EcoreUtil.resolve(it.getEObjectOrProxy(), model);
      return (!Objects.equal(model, _resolve));
    };
    this.lookupCrossReference(((CrossReference) _terminal), context, acceptor, _function);
  }

  @Override
  public void completeTypeDefinition_SuperType(final EObject model, final Assignment assignment, final ContentAssistContext context, final ICompletionProposalAcceptor acceptor) {
    AbstractElement _terminal = assignment.getTerminal();
    final Predicate<IEObjectDescription> _function = (IEObjectDescription it) -> {
      boolean _equalsIgnoreCase = it.getName().toString().equalsIgnoreCase(((ErrorType) model).getName());
      return (!_equalsIgnoreCase);
    };
    this.lookupCrossReference(((CrossReference) _terminal), context, acceptor, _function);
  }

  public List<ErrorModelLibrary> getExtendedLibraries(final ErrorModelLibrary eml, final List<ErrorModelLibrary> results) {
    List<ErrorModelLibrary> _xblockexpression = null;
    {
      final Consumer<ErrorModelLibrary> _function = (ErrorModelLibrary extEml) -> {
        results.add(extEml);
        this.getExtendedLibraries(extEml, results);
      };
      eml.getExtends().forEach(_function);
      _xblockexpression = results;
    }
    return _xblockexpression;
  }

  @Override
  public void completeTypeSetElement_Type(final EObject model, final Assignment assignment, final ContentAssistContext context, final ICompletionProposalAcceptor acceptor) {
    final EObject modelContainer = model.eContainer();
    boolean _matched = false;
    if (modelContainer instanceof ErrorPath) {
      ErrorPropagation _incoming = ((ErrorPath)modelContainer).getIncoming();
      boolean _tripleNotEquals = (_incoming != null);
      if (_tripleNotEquals) {
        _matched=true;
        this.filterTypeSetTokenTypes(((ErrorPath)modelContainer).getIncoming().getTypeSet(), model, assignment, context, acceptor);
      }
    }
    if (!_matched) {
      if (modelContainer instanceof TypeSet) {
        ErrorPath _containerOfType = EcoreUtil2.<ErrorPath>getContainerOfType(modelContainer, ErrorPath.class);
        ErrorPropagation _incoming = null;
        if (_containerOfType!=null) {
          _incoming=_containerOfType.getIncoming();
        }
        boolean _tripleNotEquals = (_incoming != null);
        if (_tripleNotEquals) {
          _matched=true;
          this.filterTypeSetTokenTypes(EcoreUtil2.<ErrorPath>getContainerOfType(modelContainer, ErrorPath.class).getIncoming().getTypeSet(), model, assignment, context, acceptor);
        }
      }
    }
    if (!_matched) {
      if (modelContainer instanceof TypeSet) {
        boolean _and = false;
        ErrorSource _containerOfType = EcoreUtil2.<ErrorSource>getContainerOfType(modelContainer, ErrorSource.class);
        NamedElement _sourceModelElement = null;
        if (_containerOfType!=null) {
          _sourceModelElement=_containerOfType.getSourceModelElement();
        }
        boolean _tripleNotEquals = (_sourceModelElement != null);
        if (!_tripleNotEquals) {
          _and = false;
        } else {
          ErrorSource _containerOfType_1 = EcoreUtil2.<ErrorSource>getContainerOfType(modelContainer, ErrorSource.class);
          NamedElement _sourceModelElement_1 = null;
          if (_containerOfType_1!=null) {
            _sourceModelElement_1=_containerOfType_1.getSourceModelElement();
          }
          _and = (_sourceModelElement_1 instanceof ErrorPropagation);
        }
        if (_and) {
          _matched=true;
          NamedElement _sourceModelElement_2 = EcoreUtil2.<ErrorSource>getContainerOfType(modelContainer, ErrorSource.class).getSourceModelElement();
          this.filterTypeSetTokenTypes(((ErrorPropagation) _sourceModelElement_2).getTypeSet(), model, assignment, context, acceptor);
        }
      }
    }
    if (!_matched) {
      if (modelContainer instanceof TypeSet) {
        ErrorSink _containerOfType = EcoreUtil2.<ErrorSink>getContainerOfType(modelContainer, ErrorSink.class);
        ErrorPropagation _incoming = null;
        if (_containerOfType!=null) {
          _incoming=_containerOfType.getIncoming();
        }
        boolean _tripleNotEquals = (_incoming != null);
        if (_tripleNotEquals) {
          _matched=true;
          this.filterTypeSetTokenTypes(EcoreUtil2.<ErrorSink>getContainerOfType(modelContainer, ErrorSink.class).getIncoming().getTypeSet(), model, assignment, context, acceptor);
        }
      }
    }
    if (!_matched) {
      if (modelContainer instanceof ErrorSource) {
        if ((((((ErrorSource)modelContainer).getSourceModelElement() != null) && (((ErrorSource)modelContainer).getSourceModelElement() instanceof ErrorPropagation)) && Objects.equal(((ErrorSource)modelContainer).getTypeTokenConstraint(), model))) {
          _matched=true;
          NamedElement _sourceModelElement = ((ErrorSource)modelContainer).getSourceModelElement();
          this.filterTypeSetTokenTypes(((ErrorPropagation) _sourceModelElement).getTypeSet(), model, assignment, context, acceptor);
        }
      }
    }
    if (!_matched) {
      if (modelContainer instanceof ErrorSource) {
        if (((((ErrorSource)modelContainer).getFailureModeReference() != null) && Objects.equal(((ErrorSource)modelContainer).getFailureModeType(), model))) {
          _matched=true;
          this.filterTypeSetTokenTypes(((ErrorSource)modelContainer).getFailureModeReference().getTypeSet(), model, assignment, context, acceptor);
        }
      }
    }
    if (!_matched) {
      if (modelContainer instanceof ErrorSink) {
        ErrorPropagation _incoming = ((ErrorSink)modelContainer).getIncoming();
        boolean _tripleNotEquals = (_incoming != null);
        if (_tripleNotEquals) {
          _matched=true;
          this.filterTypeSetTokenTypes(((ErrorSink)modelContainer).getIncoming().getTypeSet(), model, assignment, context, acceptor);
        }
      }
    }
    if (!_matched) {
      if (modelContainer instanceof ErrorBehaviorTransition) {
        if ((model instanceof TypeSet)) {
          _matched=true;
          this.filterTypeSetTokenTypes(((ErrorBehaviorTransition)modelContainer).getSource().getTypeSet(), model, assignment, context, acceptor);
        }
      }
    }
    if (!_matched) {
      if (modelContainer instanceof ErrorBehaviorTransition) {
        if (((model instanceof ConditionElement) && (((ConditionElement) model).getQualifiedErrorPropagationReference() != null))) {
          _matched=true;
          final EventOrPropagation incoming = EMV2Util.getErrorEventOrPropagation(((ConditionElement) model));
          boolean _matched_1 = false;
          if (incoming instanceof ErrorPropagation) {
            _matched_1=true;
            this.filterTypeSetTokenTypes(((ErrorPropagation)incoming).getTypeSet(), model, assignment, context, acceptor);
          }
          if (!_matched_1) {
            if (incoming instanceof ErrorEvent) {
              _matched_1=true;
              this.filterTypeSetTokenTypes(((ErrorEvent)incoming).getTypeSet(), model, assignment, context, acceptor);
            }
          }
        }
      }
    }
    if (!_matched) {
      super.completeTypeSetElement_Type(model, assignment, context, acceptor);
    }
  }

  /**
   * @since 6.0.0
   */
  public void filterTypeSetTokenTypes(final TypeSet typeSet, final EObject model, final Assignment assignment, final ContentAssistContext context, final ICompletionProposalAcceptor acceptor) {
    final ArrayList<ErrorTypes> validErrorTypesList = new ArrayList<ErrorTypes>();
    final Consumer<TypeToken> _function = (TypeToken token) -> {
      this.getValidTypes(token.getType(), validErrorTypesList);
    };
    typeSet.getTypeTokens().forEach(_function);
    AbstractElement _terminal = assignment.getTerminal();
    final Predicate<IEObjectDescription> _function_1 = (IEObjectDescription it) -> {
      boolean _xblockexpression = false;
      {
        final EObject proposedObj = EcoreUtil.resolve(it.getEObjectOrProxy(), model);
        final ArrayList<ErrorTypes> validSuperTypesOfProposed = new ArrayList<ErrorTypes>();
        if ((proposedObj instanceof ErrorTypes)) {
          this.getProposedObjectSuperTypes(((ErrorTypes)proposedObj), validSuperTypesOfProposed, proposedObj);
        }
        _xblockexpression = (validErrorTypesList.contains(proposedObj) || 
          IterableExtensions.<ErrorTypes>exists(validErrorTypesList, ((Function1<ErrorTypes, Boolean>) (ErrorTypes type) -> {
            return Boolean.valueOf(validSuperTypesOfProposed.contains(type));
          })));
      }
      return _xblockexpression;
    };
    this.lookupCrossReference(((CrossReference) _terminal), context, acceptor, _function_1);
  }

  public List<ErrorTypes> getValidTypes(final List<ErrorTypes> etsIn, final List<ErrorTypes> validErrorTypesList) {
    List<ErrorTypes> _xblockexpression = null;
    {
      if (etsIn!=null) {
        final Consumer<ErrorTypes> _function = (ErrorTypes ets) -> {
          if ((ets != null)) {
            boolean _contains = validErrorTypesList.contains(ets);
            boolean _not = (!_contains);
            if (_not) {
              validErrorTypesList.add(ets);
            }
            if ((ets instanceof TypeSet)) {
              EList<TypeToken> _typeTokens = ((TypeSet)ets).getTypeTokens();
              if (_typeTokens!=null) {
                final Consumer<TypeToken> _function_1 = (TypeToken token) -> {
                  EList<ErrorTypes> _type = null;
                  if (token!=null) {
                    _type=token.getType();
                  }
                  if (_type!=null) {
                    this.getValidTypes(_type, validErrorTypesList);
                  }
                };
                _typeTokens.forEach(_function_1);
              }
            }
          }
        };
        etsIn.forEach(_function);
      }
      _xblockexpression = validErrorTypesList;
    }
    return _xblockexpression;
  }

  public List<ErrorTypes> getProposedObjectSuperTypes(final ErrorTypes et, final List<ErrorTypes> results, final EObject proposedObj) {
    List<ErrorTypes> _xblockexpression = null;
    {
      if (((!results.contains(et)) && (!Objects.equal(et, proposedObj)))) {
        results.add(et);
      }
      if ((et instanceof ErrorType)) {
        ErrorType _superType = ((ErrorType)et).getSuperType();
        if (_superType!=null) {
          this.getProposedObjectSuperTypes(_superType, results, proposedObj);
        }
      }
      _xblockexpression = results;
    }
    return _xblockexpression;
  }
}