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: 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: 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; } 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; } }