Annotations
Annotations are meta data expressed in the Mosel source file that are stored in the resulting bim file after compilation. Thanks to a dedicated API it is possible to retrieve the information both from the model itself during its execution (see getannotations) or before/after execution from a host application (see function XPRMgetannotations in the Mosel Libraries Reference Manual).
Syntax
Annotations are organised in categories. A category groups a set of annotations and other categories (or sub-categories). When expressing a full annotation name, categories are separated by the '.' symbol. For instance:
doc.name
will be used to select the annotation name that is a member of the doc category. Similarly:
mycat1.cat2.info
will reference the annotation info recorded in the category cat2 that is itself part of category mycat1. Annotations and annotation categories must be valid Mosel identifiers: their names can only use alpha-numeric symbols plus '_'.
Some predefined categories are available at the beginning of the compilation:
- the default category (its name is empty) collects annotations that are not explicitly member of any particular category. For instance the annotation myannot will be recorded in the default category. This annotation may also be referenced by its full name .myannot
- mc (for Mosel Compiler) is used to pass information to the compiler during the compilation. For example, the mc.def annotation makes it possible to declare an annotation type (see section Declaration)
- doc can be used to document a model or package file (see section Documenting models using annotations)
In the Mosel source file annotations are included in special comments. A single-line annotation is of the form:
!@ name value
Here name is the name of the annotation (spaces between '@' and the name are ignored) and the following text (up to the end of line) its corresponding value. The separation character between the name and the value can be a space, ':' or '=' (there must be no space between the name and the symbol). There is no restriction on the content of the value: it can be any kind of text (unless the annotation is typed—see section Declaration).
A multi-line annotation is of the form:
(!@name value ... @name2 value2 ... !)
where name is an annotation name while the text following this name is its associated value. With this syntax the value may spread over several lines, its termination is marked either by the end of the comment block or by a new annotation specification. In this context, a new annotation must start with the '@' symbol at the beginning of a new line (leading spaces are ignored). As for a one-line annotation, symbols ':' and '=' can be used instead of a space to separate the name and its value.
If several annotations of the same category have to be defined in the same block, a current category may be defined such that following annotation names can be shortened. This mechanism is activated by specifying the category name terminated by a dot (the remainder of this line is ignored) before the first annotation statement. The category selection is effective for the current comment block only and remains active until the next selection. Using a dot in place of a category name restores the default behaviour (i.e. the full path must be used for annotation reference). For instance:
(!@doc. Switch to 'doc' category (this text is ignored) @name:my_function @type:integer @mycat.cat1. Switch to 'mycat.cat1' @memb1 10 @memb2 20 @. Unselect current category @glb=useless !)
Is equivalent to:
(!@doc.name:my_function @doc.type:integer @mycat.cat1.memb1 10 @mycat.cat1.memb2 20 @glb=useless !)
By default any new annotation name is added to the internal dictionary and no checking is applied to the provided value. If a given annotation is defined several times only the last assignment is preserved. The compiler will however emit a warning if an attempt is made to assign a value to a category or to use an annotation as a category. For instance:
!@mycat.memb1 10 !@mycat.memb1.memb2 20
The second definition will fail to use mycat.memb1 as a category because the first one has already implicitly declared it as an annotation.
Symbol association
An annotation is either global or associated with a specific public symbol (see section The public qualifier). The association depends on the location of the definition in the source code:
- annotations preceding a subroutine declaration (forward statement) or definition are associated with the subroutine name
- annotations preceding a declarations block are distributed to all the symbols declared in the block
- inside of a declarations block: annotations preceding or terminating the line of a declaration are associated with the corresponding symbols
In all other cases the annotations are global (i.e. not associated with any particular symbol) — in particular trying to associate annotations to private symbols will result in global annotations.
Annotations that precede a subroutine declaration, a declarations block or an entity in a declarations block can be turned into global annotations by inserting the compiler annotation mc.flush between the annotation and the following code.
Declaration
Declaration of annotations is achieved via the mc.def compiler annotation. Once an annotation is declared, the compiler checks the validity of definitions and rejects those that are not compliant, issuing a warning message (invalid annotations will not make the compilation fail unless the flag strict is used).
The general syntax of the annotation declaration statement is:
!@mc.def aname [prop1[,prop2...]]
Where aname is an annotation name and prop? a property keyword. The possible keywords are:
- alias name1 name2...
- aname Defining an alias to name1, name2...
- text|integer|real|boolean
- Type of the annotation value (default: text).
- last|first|merge|multi
-
Handling of multiple definitions of an annotation (default:
last)
- last: the last definition is kept
- first: keep the first definition (the following ones are ignored)
- merge: definitions are concatenated (separated by new lines)
- multi: all definitions are kept
- global|specific
- By default, the association of annotations depends on the location of the definition. If global is stated, the annotation is always global; with option specific, the annotation will be kept only if it can be associated with a symbol (otherwise it is ignored instead of being stored as a global one).
- values=v1 v2 v3...
- If used, this option must be the last one of the definition and it cannot be combined with range. It defines a list of possible values for the annotation.
- range=lb ub
- If used, this option must be the last one of the definition, it requires the type to be specified ( integer or real) and it cannot be combined with values. It defines a range of possible values.
- strict
- When this option has been stated any error detected on this annotation (or path when applied to a category) will make the compilation fail
Example:
!@mc.def person.name text,first,specific !@mc.def person.age integer,first,specific,range=0 150 !@mc.def person.gender values=male female
Categories are implicitly declared by the annotations they include (for instance declaring @mycat.myann implies the creation of mycat as a category). It is also possible to explicitly declare an empty category (i.e. containing no annotation) using the mc.def construct by appending a dot to the category name (the only supported property is strict). For instance:
!@mc.def mycat.
For a given annotation the declaration may be stated several times but the properties of an annotation cannot be changed. For instance, the following declarations can be used in the same source:
!@mc.def myann !@mc.def myann text,last
But the following declaration cannot be combined with any of the two preceding ones as they both result in the annotation type text:
!@mc.def myann integer
Declarations included in models are not exported to the bim file (i.e. they are only used during the compilation procedure) but declarations stated in packages are published if they are relative to a user defined category: any model using the package inherits the annotation declarations of the package.
Additional properties can be set using the mc.set compiler annotation. The general syntax of this special statement is:
!@mc.set name flag
Where name is an annotation or category name and flag one of the following keywords:
- complete
- Applied to a category this flag indicates that no other annotation can be added to this category (ignored for an annotation). It is however still possible to declare aliases. Note that sub-categories are not concerned by this flag: if required each sub-category has also to be tagged.
- disable
- Disable the named category or annotation. From the point where this flag has been set onwards, all definitions deriving from the provided name are silently ignored.
- enable
- Revert the effect of disable.
- unpublish
- Disable the automatic publication of the specified declaration.
- publish
- Publish the specified declaration.
Note that mc.set expects a full explicit name: for this command ann refers to category ann and not to annotation .ann as in other places.