/*
 * generated by Xtext
 */
package org.polarsys.chess.xtext.serializer;

import com.google.inject.Inject;
import java.util.Set;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.xtext.Action;
import org.eclipse.xtext.Parameter;
import org.eclipse.xtext.ParserRule;
import org.eclipse.xtext.serializer.ISerializationContext;
import org.eclipse.xtext.serializer.acceptor.SequenceFeeder;
import org.eclipse.xtext.serializer.sequencer.AbstractDelegatingSemanticSequencer;
import org.eclipse.xtext.serializer.sequencer.ITransientValueService.ValueTransient;
import org.polarsys.chess.xtext.flaDsl.ACIDMitigation;
import org.polarsys.chess.xtext.flaDsl.ACIDavoidable;
import org.polarsys.chess.xtext.flaDsl.Behaviour;
import org.polarsys.chess.xtext.flaDsl.Expression;
import org.polarsys.chess.xtext.flaDsl.FailureDefinition;
import org.polarsys.chess.xtext.flaDsl.FlaDslPackage;
import org.polarsys.chess.xtext.flaDsl.InFailureExpr;
import org.polarsys.chess.xtext.flaDsl.InputExpression;
import org.polarsys.chess.xtext.flaDsl.Lhs;
import org.polarsys.chess.xtext.flaDsl.NoFailureDefinition;
import org.polarsys.chess.xtext.flaDsl.OutFailureExpr;
import org.polarsys.chess.xtext.flaDsl.OutputExpression;
import org.polarsys.chess.xtext.flaDsl.Rhs;
import org.polarsys.chess.xtext.flaDsl.VariableDefinition;
import org.polarsys.chess.xtext.flaDsl.WildcardDefinition;
import org.polarsys.chess.xtext.services.FlaDslGrammarAccess;

@SuppressWarnings("all")
public class FlaDslSemanticSequencer extends AbstractDelegatingSemanticSequencer {

	@Inject
	private FlaDslGrammarAccess grammarAccess;
	
	@Override
	public void sequence(ISerializationContext context, EObject semanticObject) {
		EPackage epackage = semanticObject.eClass().getEPackage();
		ParserRule rule = context.getParserRule();
		Action action = context.getAssignedAction();
		Set<Parameter> parameters = context.getEnabledBooleanParameters();
		if (epackage == FlaDslPackage.eINSTANCE)
			switch (semanticObject.eClass().getClassifierID()) {
			case FlaDslPackage.ACID_MITIGATION:
				sequence_ACIDMitigation(context, (ACIDMitigation) semanticObject); 
				return; 
			case FlaDslPackage.ACI_DAVOIDABLE:
				sequence_ACIDavoidable(context, (ACIDavoidable) semanticObject); 
				return; 
			case FlaDslPackage.BEHAVIOUR:
				sequence_Behaviour(context, (Behaviour) semanticObject); 
				return; 
			case FlaDslPackage.EXPRESSION:
				sequence_Expression(context, (Expression) semanticObject); 
				return; 
			case FlaDslPackage.FAILURE_DEFINITION:
				sequence_FailureDefinition(context, (FailureDefinition) semanticObject); 
				return; 
			case FlaDslPackage.IN_FAILURE_EXPR:
				sequence_InFailureExpr(context, (InFailureExpr) semanticObject); 
				return; 
			case FlaDslPackage.INPUT_EXPRESSION:
				sequence_InputExpression(context, (InputExpression) semanticObject); 
				return; 
			case FlaDslPackage.LHS:
				sequence_Lhs(context, (Lhs) semanticObject); 
				return; 
			case FlaDslPackage.NO_FAILURE_DEFINITION:
				if (rule == grammarAccess.getComplexNofailureDefinitionRule()) {
					sequence_ComplexNofailureDefinition(context, (NoFailureDefinition) semanticObject); 
					return; 
				}
				else if (rule == grammarAccess.getDefinitionsRule()) {
					sequence_ComplexNofailureDefinition_NoFailureDefinition(context, (NoFailureDefinition) semanticObject); 
					return; 
				}
				else if (rule == grammarAccess.getNoFailureDefinitionRule()) {
					sequence_NoFailureDefinition(context, (NoFailureDefinition) semanticObject); 
					return; 
				}
				else break;
			case FlaDslPackage.OUT_FAILURE_EXPR:
				sequence_OutFailureExpr(context, (OutFailureExpr) semanticObject); 
				return; 
			case FlaDslPackage.OUTPUT_EXPRESSION:
				sequence_OutputExpression(context, (OutputExpression) semanticObject); 
				return; 
			case FlaDslPackage.RHS:
				sequence_Rhs(context, (Rhs) semanticObject); 
				return; 
			case FlaDslPackage.VARIABLE_DEFINITION:
				sequence_VariableDefinition(context, (VariableDefinition) semanticObject); 
				return; 
			case FlaDslPackage.WILDCARD_DEFINITION:
				sequence_WildcardDefinition(context, (WildcardDefinition) semanticObject); 
				return; 
			}
		if (errorAcceptor != null)
			errorAcceptor.accept(diagnosticProvider.createInvalidContextOrTypeDiagnostic(semanticObject, context));
	}
	
	/**
	 * Contexts:
	 *     ACIDMitigation returns ACIDMitigation
	 *
	 * Constraint:
	 *     (a=Amitigation c=Cmitigation i=Imitigation d=Dmitigation)
	 */
	protected void sequence_ACIDMitigation(ISerializationContext context, ACIDMitigation semanticObject) {
		if (errorAcceptor != null) {
			if (transientValues.isValueTransient(semanticObject, FlaDslPackage.Literals.ACID_MITIGATION__A) == ValueTransient.YES)
				errorAcceptor.accept(diagnosticProvider.createFeatureValueMissing(semanticObject, FlaDslPackage.Literals.ACID_MITIGATION__A));
			if (transientValues.isValueTransient(semanticObject, FlaDslPackage.Literals.ACID_MITIGATION__C) == ValueTransient.YES)
				errorAcceptor.accept(diagnosticProvider.createFeatureValueMissing(semanticObject, FlaDslPackage.Literals.ACID_MITIGATION__C));
			if (transientValues.isValueTransient(semanticObject, FlaDslPackage.Literals.ACID_MITIGATION__I) == ValueTransient.YES)
				errorAcceptor.accept(diagnosticProvider.createFeatureValueMissing(semanticObject, FlaDslPackage.Literals.ACID_MITIGATION__I));
			if (transientValues.isValueTransient(semanticObject, FlaDslPackage.Literals.ACID_MITIGATION__D) == ValueTransient.YES)
				errorAcceptor.accept(diagnosticProvider.createFeatureValueMissing(semanticObject, FlaDslPackage.Literals.ACID_MITIGATION__D));
		}
		SequenceFeeder feeder = createSequencerFeeder(context, semanticObject);
		feeder.accept(grammarAccess.getACIDMitigationAccess().getAAmitigationEnumRuleCall_0_0(), semanticObject.getA());
		feeder.accept(grammarAccess.getACIDMitigationAccess().getCCmitigationEnumRuleCall_2_0(), semanticObject.getC());
		feeder.accept(grammarAccess.getACIDMitigationAccess().getIImitigationEnumRuleCall_4_0(), semanticObject.getI());
		feeder.accept(grammarAccess.getACIDMitigationAccess().getDDmitigationEnumRuleCall_6_0(), semanticObject.getD());
		feeder.finish();
	}
	
	
	/**
	 * Contexts:
	 *     ACIDavoidable returns ACIDavoidable
	 *
	 * Constraint:
	 *     (a=Aavoidable c=Cavoidable i=Iavoidable d=Davoidable)
	 */
	protected void sequence_ACIDavoidable(ISerializationContext context, ACIDavoidable semanticObject) {
		if (errorAcceptor != null) {
			if (transientValues.isValueTransient(semanticObject, FlaDslPackage.Literals.ACI_DAVOIDABLE__A) == ValueTransient.YES)
				errorAcceptor.accept(diagnosticProvider.createFeatureValueMissing(semanticObject, FlaDslPackage.Literals.ACI_DAVOIDABLE__A));
			if (transientValues.isValueTransient(semanticObject, FlaDslPackage.Literals.ACI_DAVOIDABLE__C) == ValueTransient.YES)
				errorAcceptor.accept(diagnosticProvider.createFeatureValueMissing(semanticObject, FlaDslPackage.Literals.ACI_DAVOIDABLE__C));
			if (transientValues.isValueTransient(semanticObject, FlaDslPackage.Literals.ACI_DAVOIDABLE__I) == ValueTransient.YES)
				errorAcceptor.accept(diagnosticProvider.createFeatureValueMissing(semanticObject, FlaDslPackage.Literals.ACI_DAVOIDABLE__I));
			if (transientValues.isValueTransient(semanticObject, FlaDslPackage.Literals.ACI_DAVOIDABLE__D) == ValueTransient.YES)
				errorAcceptor.accept(diagnosticProvider.createFeatureValueMissing(semanticObject, FlaDslPackage.Literals.ACI_DAVOIDABLE__D));
		}
		SequenceFeeder feeder = createSequencerFeeder(context, semanticObject);
		feeder.accept(grammarAccess.getACIDavoidableAccess().getAAavoidableEnumRuleCall_0_0(), semanticObject.getA());
		feeder.accept(grammarAccess.getACIDavoidableAccess().getCCavoidableEnumRuleCall_2_0(), semanticObject.getC());
		feeder.accept(grammarAccess.getACIDavoidableAccess().getIIavoidableEnumRuleCall_4_0(), semanticObject.getI());
		feeder.accept(grammarAccess.getACIDavoidableAccess().getDDavoidableEnumRuleCall_6_0(), semanticObject.getD());
		feeder.finish();
	}
	
	
	/**
	 * Contexts:
	 *     Behaviour returns Behaviour
	 *
	 * Constraint:
	 *     rules+=Expression+
	 */
	protected void sequence_Behaviour(ISerializationContext context, Behaviour semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Contexts:
	 *     ComplexNofailureDefinition returns NoFailureDefinition
	 *
	 * Constraint:
	 *     acidMitigation=ACIDMitigation
	 */
	protected void sequence_ComplexNofailureDefinition(ISerializationContext context, NoFailureDefinition semanticObject) {
		if (errorAcceptor != null) {
			if (transientValues.isValueTransient(semanticObject, FlaDslPackage.Literals.NO_FAILURE_DEFINITION__ACID_MITIGATION) == ValueTransient.YES)
				errorAcceptor.accept(diagnosticProvider.createFeatureValueMissing(semanticObject, FlaDslPackage.Literals.NO_FAILURE_DEFINITION__ACID_MITIGATION));
		}
		SequenceFeeder feeder = createSequencerFeeder(context, semanticObject);
		feeder.accept(grammarAccess.getComplexNofailureDefinitionAccess().getAcidMitigationACIDMitigationParserRuleCall_3_0(), semanticObject.getAcidMitigation());
		feeder.finish();
	}
	
	
	/**
	 * Contexts:
	 *     Definitions returns NoFailureDefinition
	 *
	 * Constraint:
	 *     acidMitigation=ACIDMitigation?
	 */
	protected void sequence_ComplexNofailureDefinition_NoFailureDefinition(ISerializationContext context, NoFailureDefinition semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Contexts:
	 *     Expression returns Expression
	 *
	 * Constraint:
	 *     (lhs=Lhs rhs=Rhs)
	 */
	protected void sequence_Expression(ISerializationContext context, Expression semanticObject) {
		if (errorAcceptor != null) {
			if (transientValues.isValueTransient(semanticObject, FlaDslPackage.Literals.EXPRESSION__LHS) == ValueTransient.YES)
				errorAcceptor.accept(diagnosticProvider.createFeatureValueMissing(semanticObject, FlaDslPackage.Literals.EXPRESSION__LHS));
			if (transientValues.isValueTransient(semanticObject, FlaDslPackage.Literals.EXPRESSION__RHS) == ValueTransient.YES)
				errorAcceptor.accept(diagnosticProvider.createFeatureValueMissing(semanticObject, FlaDslPackage.Literals.EXPRESSION__RHS));
		}
		SequenceFeeder feeder = createSequencerFeeder(context, semanticObject);
		feeder.accept(grammarAccess.getExpressionAccess().getLhsLhsParserRuleCall_1_0(), semanticObject.getLhs());
		feeder.accept(grammarAccess.getExpressionAccess().getRhsRhsParserRuleCall_3_0(), semanticObject.getRhs());
		feeder.finish();
	}
	
	
	/**
	 * Contexts:
	 *     Definitions returns FailureDefinition
	 *     FailureDefinition returns FailureDefinition
	 *
	 * Constraint:
	 *     (type=ActualFailureType acidAvoidable=ACIDavoidable?)
	 */
	protected void sequence_FailureDefinition(ISerializationContext context, FailureDefinition semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Contexts:
	 *     InFailureExpr returns InFailureExpr
	 *
	 * Constraint:
	 *     (
	 *         failures+=WildcardDefinition | 
	 *         failures+=NoFailureDefinition | 
	 *         failures+=FailureDefinition | 
	 *         (failures+=FailureDefinition failures+=FailureDefinition+) | 
	 *         failures+=VariableDefinition
	 *     )
	 */
	protected void sequence_InFailureExpr(ISerializationContext context, InFailureExpr semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Contexts:
	 *     InputExpression returns InputExpression
	 *
	 * Constraint:
	 *     (ref=[Port|ID]? failureExpr=InFailureExpr)
	 */
	protected void sequence_InputExpression(ISerializationContext context, InputExpression semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Contexts:
	 *     Lhs returns Lhs
	 *
	 * Constraint:
	 *     (failures+=InputExpression failures+=InputExpression*)
	 */
	protected void sequence_Lhs(ISerializationContext context, Lhs semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Contexts:
	 *     NoFailureDefinition returns NoFailureDefinition
	 *
	 * Constraint:
	 *     {NoFailureDefinition}
	 */
	protected void sequence_NoFailureDefinition(ISerializationContext context, NoFailureDefinition semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Contexts:
	 *     OutFailureExpr returns OutFailureExpr
	 *
	 * Constraint:
	 *     (
	 *         failures+=NoFailureDefinition | 
	 *         failures+=ComplexNofailureDefinition | 
	 *         failures+=FailureDefinition | 
	 *         (failures+=FailureDefinition failures+=FailureDefinition+) | 
	 *         failures+=VariableDefinition
	 *     )
	 */
	protected void sequence_OutFailureExpr(ISerializationContext context, OutFailureExpr semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Contexts:
	 *     OutputExpression returns OutputExpression
	 *
	 * Constraint:
	 *     (ref=[Port|ID]? failureExpr=OutFailureExpr)
	 */
	protected void sequence_OutputExpression(ISerializationContext context, OutputExpression semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Contexts:
	 *     Rhs returns Rhs
	 *
	 * Constraint:
	 *     (failures+=OutputExpression failures+=OutputExpression*)
	 */
	protected void sequence_Rhs(ISerializationContext context, Rhs semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Contexts:
	 *     Definitions returns VariableDefinition
	 *     VariableDefinition returns VariableDefinition
	 *
	 * Constraint:
	 *     variableName=ID
	 */
	protected void sequence_VariableDefinition(ISerializationContext context, VariableDefinition semanticObject) {
		if (errorAcceptor != null) {
			if (transientValues.isValueTransient(semanticObject, FlaDslPackage.Literals.VARIABLE_DEFINITION__VARIABLE_NAME) == ValueTransient.YES)
				errorAcceptor.accept(diagnosticProvider.createFeatureValueMissing(semanticObject, FlaDslPackage.Literals.VARIABLE_DEFINITION__VARIABLE_NAME));
		}
		SequenceFeeder feeder = createSequencerFeeder(context, semanticObject);
		feeder.accept(grammarAccess.getVariableDefinitionAccess().getVariableNameIDTerminalRuleCall_1_0(), semanticObject.getVariableName());
		feeder.finish();
	}
	
	
	/**
	 * Contexts:
	 *     Definitions returns WildcardDefinition
	 *     WildcardDefinition returns WildcardDefinition
	 *
	 * Constraint:
	 *     {WildcardDefinition}
	 */
	protected void sequence_WildcardDefinition(ISerializationContext context, WildcardDefinition semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
}
