# OCL Abstract Syntax Model

The OCL Abstract Syntax Model is defined by the OCL Language 2.4 specification . We will not attempt to describe this model, here. However, the Eclipse implementation of OCL defines some extensions to this model that provide additional services. The most important of these is support for the Visitor design pattern.

### The Visitable and Visitor Interfaces

All of the metaclasses in the Abstract Syntax Model (nodes in the AST) that can be visited implement the `Visitable` interface. It define a single operation `accept(Visitor)`. This method delegates to the appropriate `visitXyz(Xyz)` method of the `Visitor` . The direct implementors of the `Visitable` interface are the `OCLExpression` and those metaclasses of the `Expressions` package that do not conform to `OCLExpression`:

- `Variable`

- `CollectionLiteralPart`

- `TupleLiteralPart`

- `ExpressionInOCL`

This last is not defined in the `Expressions` package because it pertains to the placement of OCL in `Constraint` elements in models.

The OCL parser, internally, defines a few implementations of visitors, including a `ValidationVisitor` for validating OCL expressions and an `EvaluationVisitor` for evaluating OCL expressions.

### Implementing a Visitor

The best way to implement a visitor is to extend the `AbstractVisitor` class. It provides a `result` variable of the generic type parameter type `T` to store the result computed by the visitor (optional) and a convenient pattern of selective method overrides to process only those nodes of interest for the task at hand.

The `AbstractVisitor` provides implementations of all of the `visitXyz()` interface methods that simply return the current `result` value. Furthermore, for any internal nodes of the syntax tree (such as `OperationCallExp` and `IfExp`), the `visitXyz()` methods recursively visit the child nodes, feeding the results of those descents into a `handleXyz()` method that the subclass can override to compute some result from the child results.

Thus, a subclass needs only to selectively override the default implementations of `visitXyz()` methods for leaf tree nodes and `handleXyz()` methods for non-leaves. For example, to find all variables that are declared but never used:

`OCLExpression<Classifier> expr = getExpression(); // hypothetical source of an expression
Set<Variable<Classifier, Parameter>> variables = expr.accept(
new AbstractVisitor<Set<Variable<Classifier, Parameter>>,
Classifier, Operation, Property, EnumerationLiteral,
Parameter, State, CallOperationAction, SendSignalAction, Constraint>(
new HashSet<Variable<Classifier, Parameter>>()) { // initialize the result
@Override
protected Set<Variable<Classifier, Parameter>> handleVariable(
Variable<Classifier, Parameter> variable,
Set<Variable<Classifier, Parameter>> initResult) {
result.add(variable);
return result;
}
@Override
public Set<Variable<Classifier, Parameter>> visitVariableExp(
VariableExp<Classifier, Parameter> v) {
result.remove(v.getReferredVariable());
return result;
}
}});
Set<String> varNames = new HashSet<String>();
for (Variable<?, ?> next : variables) {
varNames.add(next.getName());
}
System.out.println("Unused variables: + " varNames);
`

### The OppositePropertyCallExp Extension

In Ecore models, a reference may have defined an `opposite` reference, usually owned by the class that is the type of the forward reference. An opposite reference has several, often undesirable or even prohibitive, implications on the class owning it:

- A getter and, for settable features with upper multiplicity 1, a setter will be added, requiring the class to know the class owning the forward reference. This would create cyclic component references if the two classes lived in different components and would therefore not be possible.

- The default serialization format and usually the storage format for non-default model stores changes to include the opposite reference.

Yet, particularly for expressing constraints over the instance models it is often instrumental to be able to navigate such forward references also in reverse. The `OppositePropertyCallExp` class which inherits from `NavigationCallExp` and is sibling of `PropertyCallExp` allows for this reverse navigation in OCL. It points to the forward reference, and its semantics are to navigate this reference in reverse.

To allow for convenient creation of such expressions in the OCL concrete syntax, the standard property call syntax, such as `self.x` can be used, where `x` is not the name of a forward reference on `self`'s class but rather an annotated name on a reference using `self`'s class or any of its base classes as its type. To enable this feature, use the special environment factory class `EcoreEnvironmentFactoryWithHiddenOpposites` when initializing the OCL environment, e.g., by passing such an object to the `OCL.newInstance(...)` method.

The name for the reverse navigation can be specified by an `EAnnotation` with source `http://schema.omg.org/spec/MOF/2.0/emof.xml` and with details key `Property.oppositeRoleName`. The details value contains the name by which the “hidden” opposite can be referred to in OCL expressions.

If OCL delegates are to be used, the standard EPackage annotations with `invocationDelegate`, `settingDelegate` and `validationDelegate` details for the `http://www.eclipse.org/emf/2002/Ecore` source must be augmented as shown by a further `hiddenOpposites` detail for the `http://www.eclipse.org/emf/2002/Ecore/OCL` source.

This additional annotation causes the `EnvironmentFactory` functionality for the EPackage to be provided by an instance of the `EcoreEnvironmentFactoryWithHiddenOpposites` class which uses the `DefaultOppositeEndFinder` class will be used for finding and navigating the hidden opposites. More substantial customisation is possible by specifying an `environmentFactoryClass` detail with the fully qualified name of a derived `EcoreEnvironmentFactory` that provides a constructor taking an `EPackage.Registry` argument. Note, that the class specified must be visible by your Ecore model’s bundle.