#
Bootstrapped Metamodel
Klass has a metamodel; a model of models. In fact, it has several representations of the same metamodel.
- The Abstract Syntax Tree used internally by the compiler.
- The in-memory DomainModel object returned upon successful compilation.
- The bootstrapped metamodel.
- etc.
The bootstrapped metamodel is expressed like a regular model. The first few meta-types are defined like this:
klass
package klass.model.meta.domain
interface Element
{
}
interface NamedElement
implements Element
{
name: String key maximumLength(256);
ordinal: Integer private;
}
class PackageableElement
abstract
implements NamedElement
{
packageName: String maximumLength(100000);
}
class Classifier
abstract
extends PackageableElement
{
}
class Klass
extends Classifier
{
superClassName: String? private maximumLength(256);
abstractClass: Boolean;
}
enumeration PrimitiveType
{
INTEGER("Integer"),
LONG("Long"),
DOUBLE("Double"),
FLOAT("Float"),
BOOLEAN("Boolean"),
STRING("String"),
INSTANT("Instant"),
LOCAL_DATE("LocalDate"),
TEMPORAL_INSTANT("TemporalInstant"),
TEMPORAL_RANGE("TemporalRange"),
}
enumeration Multiplicity
{
ZERO_TO_ONE("0..1"),
ONE_TO_ONE("1..1"),
ZERO_TO_MANY("0..*"),
ONE_TO_MANY("1..*"),
}
class DataTypeProperty
abstract
implements NamedElement
{
classifierName : String key maximumLength(256);
optional : Boolean;
}
class PrimitiveProperty
extends DataTypeProperty
{
primitiveType : PrimitiveType maximumLength(256);
}
association ClassifierHasDataTypeTypeProperties
{
owningClassifier : Classifier[1..1];
dataTypeProperties : DataTypeProperty[0..*] owned
orderBy: this.ordinal ascending;
}
The full source is too large to include here. It defines enumeration, class, association, projection, and service, plus their parts.
The bootstrapped metamodel allows us to work with metadata like regular data. It defines some projections and services which return model data. For example, here's the service to get a class by its name:
klass
package klass.model.meta.domain
projection KlassProjection on Klass
{
name: "NamedElement name",
packageName: "PackageableElement packageName",
abstractClass: "Klass abstractClass",
superInterfaces: ClassifierInterfaceMappingProjection,
classifierModifiers: ClassifierModifierProjection,
dataTypeProperties: DataTypePropertyProjection,
superClass: {
name: "NamedElement name",
},
associationEnds: {
name: "NamedElement name",
},
parameterizedProperties: ParameterizedPropertyProjection,
}
service KlassResource on Klass
{
/meta/class/{name: String[1..1]}
GET
{
multiplicity: one;
criteria : this.name == name;
projection : KlassProjection;
}
/meta/class
GET
{
multiplicity: many;
criteria : all;
projection : KlassProjection;
orderBy : this.ordinal ascending;
}
}