Aadl2DerivedStateComputer.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.resource;

import com.google.inject.ConfigurationException;
import com.google.inject.Injector;
import com.google.inject.Singleton;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.function.Consumer;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.xtext.Grammar;
import org.eclipse.xtext.nodemodel.INode;
import org.eclipse.xtext.parser.IParseResult;
import org.eclipse.xtext.resource.DerivedStateAwareResource;
import org.eclipse.xtext.resource.IDerivedStateComputer;
import org.eclipse.xtext.xbase.lib.Exceptions;
import org.eclipse.xtext.xbase.lib.IterableExtensions;
import org.osate.aadl2.AadlPackage;
import org.osate.aadl2.AnnexLibrary;
import org.osate.aadl2.AnnexSubclause;
import org.osate.aadl2.Classifier;
import org.osate.aadl2.DefaultAnnexLibrary;
import org.osate.aadl2.DefaultAnnexSubclause;
import org.osate.aadl2.NamedElement;
import org.osate.aadl2.PackageSection;
import org.osate.annexsupport.AnnexUtil;
import org.osate.annexsupport.ParseResultHolder;

@Singleton
@SuppressWarnings("all")
public class Aadl2DerivedStateComputer implements IDerivedStateComputer {
  @Override
  public void installDerivedState(final DerivedStateAwareResource resource, final boolean preLinkingPhase) {
    final ArrayList<NamedElement> annexElements = Aadl2DerivedStateComputer.getAllAnnexElements(resource);
    final ArrayList<Injector> injectors = Aadl2DerivedStateComputer.collectInjectors(annexElements);
    for (final Injector injector : injectors) {
      try {
        final IDerivedStateComputer dsc = injector.<IDerivedStateComputer>getInstance(IDerivedStateComputer.class);
        dsc.installDerivedState(resource, preLinkingPhase);
      } catch (final Throwable _t) {
        if (_t instanceof ConfigurationException) {
        } else {
          throw Exceptions.sneakyThrow(_t);
        }
      }
    }
  }

  @Override
  public void discardDerivedState(final DerivedStateAwareResource resource) {
    final ArrayList<NamedElement> annexElements = Aadl2DerivedStateComputer.getAllAnnexElements(resource);
    final ArrayList<Injector> injectors = Aadl2DerivedStateComputer.collectInjectors(annexElements);
    final Consumer<Injector> _function = (Injector injector) -> {
      try {
        injector.<IDerivedStateComputer>getInstance(IDerivedStateComputer.class).discardDerivedState(resource);
      } catch (final Throwable _t) {
        if (_t instanceof ConfigurationException) {
        } else {
          throw Exceptions.sneakyThrow(_t);
        }
      }
    };
    injectors.forEach(_function);
  }

  public static ArrayList<NamedElement> getAllAnnexElements(final Resource resource) {
    ArrayList<NamedElement> _xblockexpression = null;
    {
      final TreeIterator<Object> allContents = EcoreUtil.<Object>getAllContents(resource, false);
      final ArrayList<NamedElement> result = new ArrayList<NamedElement>();
      try {
        while (allContents.hasNext()) {
          {
            Object _next = allContents.next();
            final EObject object = ((EObject) _next);
            final EObject parent = object.eContainer();
            if ((!(parent instanceof AadlPackage))) {
              if ((parent instanceof PackageSection)) {
                if ((object instanceof DefaultAnnexLibrary)) {
                  AnnexLibrary _parsedAnnexLibrary = ((DefaultAnnexLibrary)object).getParsedAnnexLibrary();
                  boolean _tripleNotEquals = (_parsedAnnexLibrary != null);
                  if (_tripleNotEquals) {
                    AnnexLibrary _parsedAnnexLibrary_1 = ((DefaultAnnexLibrary)object).getParsedAnnexLibrary();
                    result.add(_parsedAnnexLibrary_1);
                  }
                  allContents.prune();
                }
              } else {
                if ((parent instanceof Classifier)) {
                  if ((object instanceof DefaultAnnexSubclause)) {
                    AnnexSubclause _parsedAnnexSubclause = ((DefaultAnnexSubclause)object).getParsedAnnexSubclause();
                    boolean _tripleNotEquals_1 = (_parsedAnnexSubclause != null);
                    if (_tripleNotEquals_1) {
                      AnnexSubclause _parsedAnnexSubclause_1 = ((DefaultAnnexSubclause)object).getParsedAnnexSubclause();
                      result.add(_parsedAnnexSubclause_1);
                    }
                  }
                  allContents.prune();
                } else {
                  if ((parent != null)) {
                    allContents.prune();
                  }
                }
              }
            }
          }
        }
      } catch (final Throwable _t) {
        if (_t instanceof IndexOutOfBoundsException) {
        } else {
          throw Exceptions.sneakyThrow(_t);
        }
      }
      _xblockexpression = result;
    }
    return _xblockexpression;
  }

  public static ArrayList<Injector> collectInjectors(final List<NamedElement> annexElements) {
    ArrayList<Injector> _xblockexpression = null;
    {
      final HashSet<String> names = new HashSet<String>();
      final ArrayList<Injector> injectors = new ArrayList<Injector>();
      for (final NamedElement annex : annexElements) {
        boolean _contains = names.contains(annex.getName());
        boolean _not = (!_contains);
        if (_not) {
          final IParseResult annexParseResult = ParseResultHolder.Factory.INSTANCE.adapt(annex).getParseResult();
          if ((annexParseResult != null)) {
            final Injector injector = AnnexUtil.getInjector(annexParseResult);
            if ((injector != null)) {
              injectors.add(injector);
            }
            String _name = annex.getName();
            names.add(_name);
          }
        }
      }
      _xblockexpression = injectors;
    }
    return _xblockexpression;
  }

  public static String getGrammarName(final INode node) {
    String _xblockexpression = null;
    {
      final Resource grammarResource = node.getGrammarElement().eResource();
      final EObject grammar = IterableExtensions.<EObject>head(grammarResource.getContents());
      String _xifexpression = null;
      if ((grammar instanceof Grammar)) {
        _xifexpression = ((Grammar)grammar).getName();
      } else {
        _xifexpression = null;
      }
      _xblockexpression = _xifexpression;
    }
    return _xblockexpression;
  }
}