Integration with EMF

Xtext relies heavily on EMF internally, but it can also be used as the serialization back-end of other EMF-based tools.

XtextResource Implementation

Xtext provides an implementation of EMF’s resource, the XtextResource. This does not only encapsulate the parser that converts text to an EMF model but also the serializer working the opposite direction. That way, an Xtext model just looks like any other Ecore-based model from the outside, making it amenable for the use by other EMF based tools. In fact, the Xpand templates in the generator plug-in created by the Xtext wizard do not make any assumption on the fact that the model is described in Xtext, and they would work fine with any model based on the same Ecore model of the language. So in the ideal case, you can switch the serialization format of your models to your self-defined DSL by just replacing the resource implementation used by your other modeling tools.

The generator fragment ResourceFactoryFragment registers a factory for the XtextResource to EMF’s resource factory registry, such that all tools using the default mechanism to resolve a resource implementation will automatically get that resource implementation.

Using a self-defined textual syntax as the primary storage format has a number of advantages over the default XMI serialization, e.g.

Xtext targets easy to use and naturally feeling languages. It focuses on the lexical aspects of a language a bit more than on the semantic ones. As a consequence, a referenced Ecore model can contain more concepts than are actually covered by the Xtext grammar. As a result, not everything that is possibly expressed in the EMF model can be serialized back into a textual representation with regards to the grammar. So if you want to use Xtext to serialize your models as described above, it is good to have a couple of things in mind:

Fragment Provider (referencing Xtext models from other EMF artifacts)

Although inter-Xtext linking is not done by URIs, you may want to be able to reference your EObject from non-Xtext models. In those cases URIs are used, which are made up of a part identifying the resource. Each EObject contained in a resource can be identified by a so called fragment.

A fragment is a part of an EMF URI and needs to be unique per resource.

The generic XMI resource shipped with EMF provides a generic path-like computation of fragments. With an XMI or other binary-like serialization it is also common and possible to use UUIDs.

However with a textual concrete syntax we want to be able to compute fragments out of the given information. We don’t want to force people to use UUIDs (i.e. synthetic identifiers) or relative generic paths (very fragile), in order to refer to EObjects.

Therefore one can contribute a so called IFragmentProvider per language.

public interface IFragmentProvider extends ILanguageService {
 
  /**
   * Computes the local ID of the given object. 
   * @param obj
   *            The EObject to compute the fragment for
   * @return the fragment, which can be an arbitrary string but must be 
   *         unique within a resource. Return null to use default 
   *         implementation
   */
  String getFragment(EObject obj);
  
  /**
   * Locates an EObject in a resource by its fragment. 
   * @return the EObject 
   */
  EObject getEObject(Resource resource, String fragment);
}

Note that the currently available default fragment provider does nothing (i.e. falls back to the default behavior of EMF).