Holding scalar values would not get as far. To increase expressiveness of our languages nodes are allowed to store references to other nodes. Each reference has a name, a type, and a cardinality. The type restricts the allowed type of a reference target. Cardinality defines how many references of this kind a node can have. References can only have two types of cardinalities: 1:0..1 and 1:1.
For references there is no direct way to traverse them in the reverse direction. The
jetbrains.mps.lang.findUsages language and the
execute finder should be used for that. (These do not work reliably during generation).
To compose nodes into trees, we need to allow children to be hooked up to them. Each child declaration holds a target concept, its role and cardinality. Target concept specifies the type of children. Role specifies the name for this group of children. Finally, cardinality specifies how many children from this group can be contained in a single node. There are 4 allowed types of cardinality: 1:1, 1:0..1, 1:0..n, and 1:1..n.
Programatically, node.children retrieves all nodes that are children to the current node. The reverse of node.children is node.parent or node.ancestor(s).