diff --git a/.gitignore b/.gitignore index 988b127..6bd25a8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ # temp files ~$* +.asciidoctor/ \ No newline at end of file diff --git a/index.adoc b/index.adoc index e293ae2..e544f4a 100644 --- a/index.adoc +++ b/index.adoc @@ -1,7 +1,7 @@ = LIonWeb Documentation * xref:documentation/use-cases.adoc[Use cases] -* xref:lioncore/metametamodel.adoc[Meta-meta-model (M3)] +* xref:lioncore/metametamodel/metametamodel.adoc[Meta-meta-model (M3)] // * xref:lioncore/model-representations.adoc[Models representations] -* xref:lioncore/serialization.adoc[Serialization format] +* xref:lioncore/serialization/serialization.adoc[Serialization format] diff --git a/lioncore/issue-footnotes.adoc b/lioncore/issue-footnotes.adoc index 772fd6d..63653cb 100644 --- a/lioncore/issue-footnotes.adoc +++ b/lioncore/issue-footnotes.adoc @@ -1,11 +1,46 @@ -:fn-java33: footnote:java33[https://github.com/LIonWeb-org/lioncore-java/issues/33[Require empty members in serialization #33]] +// To update +// 1. `gh issue list --state all --limit 1000 > issues.txt` in `organizations` repo dir +// 2. Use Excel to delete all columns except id and title +// 3. Paste here +// 4. Run search/replace with +// search: ([0-9]+)\t(.+) +// replace: :fn-org$1: footnote:org$1[https://github.com/LIonWeb-org/organization/issues/$1\[$2 #$1]] +// 5. Use Notepad++ to +// a) Edit | Line Operations | Sort Lines As Integers Ascending +// b) Edit | Line Operations | Remove Duplicate Lines -:fn-org6: footnote:org6[https://github.com/LIonWeb-org/organization/issues/6[How to represent DerivedFeature in M3? #6]] +:fn-java33: footnote:java33[https://github.com/LIonWeb-org/lioncore-java/issues/33[Require empty members in serialization #33]] +:fn-org3: footnote:org3[https://github.com/LIonWeb-org/organization/issues/3[Use Cases for Repo Access API #3]] +:fn-org4: footnote:org4[https://github.com/LIonWeb-org/organization/issues/4[If and how to represent ordered / unordered containments in M3 #4]] +:fn-org5: footnote:org5[https://github.com/LIonWeb-org/organization/issues/5[First-class support of Enums in M3 #5]] +:fn-org6: footnote:org6[https://github.com/LIonWeb-org/organization/issues/6[How to represent ComputedFeature in M3? #6]] :fn-org7: footnote:org7[https://github.com/LIonWeb-org/organization/issues/7[Is version part of M3 Metamodel? #7]] :fn-org8: footnote:org8[https://github.com/LIonWeb-org/organization/issues/8[Which parts of a link can be specialized? #8]] :fn-org9: footnote:org9[https://github.com/LIonWeb-org/organization/issues/9[Supported built-in primitive types #9]] -:fn-org9-intrange: footnote:org9[https://github.com/LIonWeb-org/organization/issues/9#issuecomment-1288624098[Discussion on supported integer range]] +:fn-org9-implicit: footnote:org9implicit[https://github.com/LIonWeb-org/organization/issues/9#issuecomment-1381934044[Discussion on implicitly importing stdlib]] +:fn-org9-intrange: footnote:org9intrange[https://github.com/LIonWeb-org/organization/issues/9#issuecomment-1288624098[Discussion on supported integer range]] +:fn-org10: footnote:org10[https://github.com/LIonWeb-org/organization/issues/10[Support custom DataTypes? #10]] +:fn-org11: footnote:org11[https://github.com/LIonWeb-org/organization/issues/11[Which M3 things can be annotated? #11]] +:fn-org12: footnote:org12[https://github.com/LIonWeb-org/organization/issues/12[Annotation instances shipped by default #12]] :fn-org13: footnote:org13[https://github.com/LIonWeb-org/organization/issues/13[If and how to represent Annotations in M3 #13]] +:fn-org14: footnote:org14[https://github.com/LIonWeb-org/organization/issues/14[Main feature annotation #14]] +:fn-org15: footnote:org15[https://github.com/LIonWeb-org/organization/issues/15[Support commentable nodes #15]] +:fn-org16: footnote:org16[https://github.com/LIonWeb-org/organization/issues/16[Have a default way to manage derived properties of nodes #16]] +:fn-org17: footnote:org17[https://github.com/LIonWeb-org/organization/issues/17[License for LIonWeb #17]] +:fn-org18: footnote:org18[https://github.com/LIonWeb-org/organization/issues/18[How to use GitHub features #18]] +:fn-org19: footnote:org19[https://github.com/LIonWeb-org/organization/issues/19[Are M3 elements a node<> (meta-circularity)? #19]] +:fn-org20: footnote:org20[https://github.com/LIonWeb-org/organization/issues/20[Typedef discussion (was: Comments on M3) #20]] +:fn-org22: footnote:org22[https://github.com/LIonWeb-org/organization/issues/22[Change Multiplicity removing 1..* and leaving only 0..1, 1..1, and 0..* #22]] +:fn-org23: footnote:org23[https://github.com/LIonWeb-org/organization/issues/23[Repository federation #23]] +:fn-org24: footnote:org24[https://github.com/LIonWeb-org/organization/issues/24[Iterations on repository API #24]] +:fn-org25: footnote:org25[https://github.com/LIonWeb-org/organization/issues/25[Repo API: Bulk read/write #25]] +:fn-org26: footnote:org26[https://github.com/LIonWeb-org/organization/issues/26[Repo API: Versioning / Collaboration #26]] +:fn-org27: footnote:org27[https://github.com/LIonWeb-org/organization/issues/27[Repo API: Access control #27]] +:fn-org28: footnote:org28[https://github.com/LIonWeb-org/organization/issues/28[Repo API: Change-based event notifications #28]] +:fn-org29: footnote:org29[https://github.com/LIonWeb-org/organization/issues/29[Repo API: Do we need model partitions? #29]] +:fn-org30: footnote:org30[https://github.com/LIonWeb-org/organization/issues/30[Repo API: Locking #30]] +:fn-org31: footnote:org31[https://github.com/LIonWeb-org/organization/issues/31[Repo API: Node IDs #31]] +:fn-org32: footnote:org32[https://github.com/LIonWeb-org/organization/issues/32[Can we have multiple instances of the same Annotation associated to a certain Node? #32]] :fn-org33: footnote:org33[https://github.com/LIonWeb-org/organization/issues/33[Repo API: Node representation #33]] :fn-org34: footnote:org34[https://github.com/LIonWeb-org/organization/issues/34[Repo API: Property value encondings #34]] :fn-org35: footnote:org35[https://github.com/LIonWeb-org/organization/issues/35[Repo API: Represent dangling pointers #35]] @@ -13,28 +48,97 @@ :fn-org36-null: footnote:org36null[https://github.com/LIonWeb-org/organization/issues/36#issuecomment-1384070433[Meaning and rationale of `null` values for reference id and resolveInfo]] :fn-org37: footnote:org37[https://github.com/LIonWeb-org/organization/issues/37[Repo API: Node serialization #37]] :fn-org37-name: footnote:org37conc[https://github.com/LIonWeb-org/organization/issues/37#issuecomment-1411857068[Discussion on name `concept`]] +:fn-org38: footnote:org38[https://github.com/LIonWeb-org/organization/issues/38[Additional API: Deliver repo contents according to M2-based JSON schema #38]] +:fn-org39: footnote:org39[https://github.com/LIonWeb-org/organization/issues/39[Additional API: Complex queries #39]] +:fn-org40: footnote:org40[https://github.com/LIonWeb-org/organization/issues/40[Define a standard way to represent model diffs #40]] +:fn-org43: footnote:org43[https://github.com/LIonWeb-org/organization/issues/43[Is model API (PM3) part of LIonWeb spec? #43]] +:fn-org44: footnote:org44[https://github.com/LIonWeb-org/organization/issues/44[Create consolidated document to list all "agreed-upon" parts #44]] +:fn-org46: footnote:org46[https://github.com/LIonWeb-org/organization/issues/46[Add id field to MetamodelElement and Metamodel #46]] +:fn-org48: footnote:org48[https://github.com/LIonWeb-org/organization/issues/48[Allowed characters for names in metamodels #48]] :fn-org50: footnote:org50[https://github.com/LIonWeb-org/organization/issues/50[Metamodel dependencies: explicit, transitive? #50]] +:fn-org51: footnote:org51[https://github.com/LIonWeb-org/organization/issues/51[API Structuring #51]] +:fn-org53: footnote:org53[https://github.com/LIonWeb-org/organization/issues/53[Ids for M3 Elements #53]] +:fn-org54: footnote:org54[https://github.com/LIonWeb-org/organization/issues/54[Remove `NamespaceEntity.container` from M3 #54]] :fn-org55: footnote:org55[https://github.com/LIonWeb-org/organization/issues/55[Always provide both containment and parent id in serialization #55]] -:fn-org55-name-references: footnote:org55ref[https://github.com/LIonWeb-org/organization/issues/55#issuecomment-1415994431[Discussion on names `references` and `reference`]] :fn-org55-name-children: footnote:org55child[https://github.com/LIonWeb-org/organization/issues/55#issuecomment-1409321113[Discussion on name `children`]] +:fn-org55-name-references: footnote:org55ref[https://github.com/LIonWeb-org/organization/issues/55#issuecomment-1415994431[Discussion on names `references` and `reference`]] :fn-org57: footnote:org57[https://github.com/LIonWeb-org/organization/issues/57[Supported reference targets #57]] :fn-org58: footnote:org58[https://github.com/LIonWeb-org/organization/issues/58[Include serialization format version in serialization #58]] :fn-org59: footnote:org59[https://github.com/LIonWeb-org/organization/issues/59[Require empty members in serialization #59]] +:fn-org61: footnote:org61[https://github.com/LIonWeb-org/organization/issues/61[Goal and Scope of LionWeb #61]] :fn-org62: footnote:org62[https://github.com/LIonWeb-org/organization/issues/62[How to store invalid text typed at arbitrary places? #62]] +:fn-org63: footnote:org63[https://github.com/LIonWeb-org/organization/issues/63[Formulate minimal integration path - the “demo app” #63]] +:fn-org64: footnote:org64[https://github.com/LIonWeb-org/organization/issues/64[How should serialization work? #64]] +:fn-org66: footnote:org66[https://github.com/LIonWeb-org/organization/issues/66[Migrate diagrams from PlantUML to Mermaid #66]] :fn-org67: footnote:org67[https://github.com/LIonWeb-org/organization/issues/67[Allow additional info in serialization #67]] +:fn-org68: footnote:org68[https://github.com/LIonWeb-org/organization/issues/68[Model State Token in the Bulk API -- first step to concurrency and versioning #68]] +:fn-org69: footnote:org69[https://github.com/LIonWeb-org/organization/issues/69[Node update: do we allow concept change? #69]] +:fn-org70: footnote:org70[https://github.com/LIonWeb-org/organization/issues/70[Can Repositories have stricter requirements on node IDs than LIonWeb (e.g. only longs)? #70]] :fn-org71: footnote:org71[https://github.com/LIonWeb-org/organization/issues/71[Do we need to represent BaseConcept? #71]] +:fn-org72: footnote:org72[https://github.com/LIonWeb-org/organization/issues/72[Do we specify how language evolution works? #72]] :fn-org73: footnote:org73[https://github.com/LIonWeb-org/organization/issues/73[We don't care about serialization verbosity #73]] -:fn-org76: footnote:org76[https://github.com/LIonWeb-org/organization/issues/76[Should serialization contain a list of used metamodels? #76]] +:fn-org74: footnote:org74[https://github.com/LIonWeb-org/organization/issues/74[Node validation #74]] +:fn-org75: footnote:org75[https://github.com/LIonWeb-org/organization/issues/75[Bulk API atomicity #75]] +:fn-org76: footnote:org76[https://github.com/LIonWeb-org/organization/issues/76[Should serialization contain a list of used languages? #76]] :fn-org77: footnote:org77[https://github.com/LIonWeb-org/organization/issues/77[Rename Metamodel.qualifiedName to name #77]] :fn-org78: footnote:org78[https://github.com/LIonWeb-org/organization/issues/78[Rename M3 Metamodel to Language? #78]] +:fn-org80: footnote:org80[https://github.com/LIonWeb-org/organization/issues/80[Metamodel.id/NamespacedEntity.id vs. Node id #80]] +:fn-org82: footnote:org82[https://github.com/LIonWeb-org/organization/issues/82[How to represent non-existent nodes in serialization? #82]] +:fn-org83: footnote:org83[https://github.com/LIonWeb-org/organization/issues/83[Write down what model correctness is #83]] :fn-org84: footnote:org84[https://github.com/LIonWeb-org/organization/issues/84[Rename NamespacedEntity.simpleName to name? #84]] +:fn-org86: footnote:org86[https://github.com/LIonWeb-org/organization/issues/86[Introducing the builtin interface INamed #86]] +:fn-org87: footnote:org87[https://github.com/LIonWeb-org/organization/issues/87[Use id + resolveInfo for references to the meta-model. #87]] :fn-org89: footnote:org89[https://github.com/LIonWeb-org/organization/issues/89[Establish term meta-pointer #89]] :fn-org90: footnote:org90[https://github.com/LIonWeb-org/organization/issues/90[Rename M3 property id -> key #90]] :fn-org91: footnote:org91[https://github.com/LIonWeb-org/organization/issues/91[Requirements on metamodel keys #91]] :fn-org92: footnote:org92[https://github.com/LIonWeb-org/organization/issues/92[Add version property to M3 Metamodel #92]] +:fn-org93: footnote:org93[https://github.com/LIonWeb-org/organization/issues/93[Change serialization format to use meta-pointers #93]] +:fn-org94: footnote:org94[https://github.com/LIonWeb-org/organization/issues/94[Provide id mapping API #94]] +:fn-org95: footnote:org95[https://github.com/LIonWeb-org/organization/issues/95[In-process API for processors #95]] +:fn-org96: footnote:org96[https://github.com/LIonWeb-org/organization/issues/96[Describe ResolveInfo as per latest conclusions #96]] :fn-org97: footnote:org97[https://github.com/LIonWeb-org/organization/issues/97[Name clashes during inheritance #97]] :fn-org100: footnote:org100[https://github.com/LIonWeb-org/organization/issues/100[Do we allow + prefix for integer property values? #100]] :fn-org101: footnote:org101[https://github.com/LIonWeb-org/organization/issues/101[Rename MetamodelElement to LanguageElement? #101]] +:fn-org103: footnote:org103[https://github.com/LIonWeb-org/organization/issues/103[Rename DerivedFeatures to avoid confusion with Derived Models #103]] +:fn-org104: footnote:org104[https://github.com/LIonWeb-org/organization/issues/104[Interfaces vs. (abstract) Concepts vs. Multiple Inheritance #104]] +:fn-org105: footnote:org105[https://github.com/LIonWeb-org/organization/issues/105[Rename FeaturesContainer to Classifier #105]] +:fn-org106: footnote:org106[https://github.com/LIonWeb-org/organization/issues/106[[documentation] Aim of LIonWeb #106]] +:fn-org107: footnote:org107[https://github.com/LIonWeb-org/organization/issues/107[[documentation] Summary of core concepts #107]] +:fn-org108: footnote:org108[https://github.com/LIonWeb-org/organization/issues/108[[documentation] Use cases #108]] +:fn-org109: footnote:org109[https://github.com/LIonWeb-org/organization/issues/109[[documentation] Roadmap #109]] +:fn-org110: footnote:org110[https://github.com/LIonWeb-org/organization/issues/110[[documentation] Contributing #110]] +:fn-org111: footnote:org111[https://github.com/LIonWeb-org/organization/issues/111[[documentation: How-to guides] Implementations #111]] +:fn-org112: footnote:org112[https://github.com/LIonWeb-org/organization/issues/112[[documentation: How-to guides] How to create a metamodel #112]] +:fn-org113: footnote:org113[https://github.com/LIonWeb-org/organization/issues/113[[documentation: How-to guides] How to use the API #113]] +:fn-org114: footnote:org114[https://github.com/LIonWeb-org/organization/issues/114[[documentation: How-to guides] How to deserialize a model #114]] +:fn-org115: footnote:org115[https://github.com/LIonWeb-org/organization/issues/115[[documentation: How-to guides] How to serialize a model #115]] +:fn-org116: footnote:org116[https://github.com/LIonWeb-org/organization/issues/116[[documentation: How-to guides] How to implement model queries #116]] +:fn-org117: footnote:org117[https://github.com/LIonWeb-org/organization/issues/117[[documentation: How-to guides] How to evolve a metamodel #117]] +:fn-org118: footnote:org118[https://github.com/LIonWeb-org/organization/issues/118[[documentation: How-to guides] How to implement a type system #118]] +:fn-org119: footnote:org119[https://github.com/LIonWeb-org/organization/issues/119[[documentation: Explanation] How do references work #119]] +:fn-org120: footnote:org120[https://github.com/LIonWeb-org/organization/issues/120[[documentation: Explanation] How does language reuse work #120]] +:fn-org121: footnote:org121[https://github.com/LIonWeb-org/organization/issues/121[[documentation: Reference] Working principles #121]] +:fn-org122: footnote:org122[https://github.com/LIonWeb-org/organization/issues/122[[documentation: Reference] Layering: data interchange “vs.” programmatic #122]] +:fn-org123: footnote:org123[https://github.com/LIonWeb-org/organization/issues/123[[documentation: Reference] Reference architecture #123]] +:fn-org124: footnote:org124[https://github.com/LIonWeb-org/organization/issues/124[[documentation: Reference] Serialization format #124]] +:fn-org125: footnote:org125[https://github.com/LIonWeb-org/organization/issues/125[[documentation: Reference] LIonCore/M3 #125]] +:fn-org126: footnote:org126[https://github.com/LIonWeb-org/organization/issues/126[[documentation: Reference] Model correctness #126]] +:fn-org127: footnote:org127[https://github.com/LIonWeb-org/organization/issues/127[[documentation: Reference] API (bulk mode) #127]] :fn-org128: footnote:org128[https://github.com/LIonWeb-org/organization/issues/128[Refer to EnumLiteral by key? #128]] +:fn-org129: footnote:org129[https://github.com/LIonWeb-org/organization/issues/129[Establish name for entries in serialization/languages? #129]] :fn-org130: footnote:org130[https://github.com/LIonWeb-org/organization/issues/130[What does Language.version mean semantically? #130]] -:fn-org131: footnote:org131[https://github.com/LIonWeb-org/organization/issues/131[How to refer from one language to another? #131]] \ No newline at end of file +:fn-org131: footnote:org131[https://github.com/LIonWeb-org/organization/issues/131[How to refer from one language to another? #131]] +:fn-org132: footnote:org132[https://github.com/LIonWeb-org/organization/issues/132[Sending a sub-tree to be attached to an existing parent #132]] +:fn-org134: footnote:org134[https://github.com/LIonWeb-org/organization/issues/134[Integrate use cases from Munich discussion into docs #134]] +:fn-org135: footnote:org135[https://github.com/LIonWeb-org/organization/issues/135[Promote LIonWeb with other tool providers #135]] +:fn-org136: footnote:org136[https://github.com/LIonWeb-org/organization/issues/136[Establish global symbol index #136]] +:fn-org139: footnote:org139[https://github.com/LIonWeb-org/organization/issues/139[Disallow redefining / overriding inherited feature #139]] +:fn-org141: footnote:org141[https://github.com/LIonWeb-org/organization/issues/141[Key of builtin stdlib #141]] +:fn-org142: footnote:org142[https://github.com/LIonWeb-org/organization/issues/142[Shall we have `IKeyed` interface in M3? #142]] +:fn-org143: footnote:org143[https://github.com/LIonWeb-org/organization/issues/143[Is M3 `NamespacedEntity` an abstract concept or interface? #143]] +:fn-org144: footnote:org144[https://github.com/LIonWeb-org/organization/issues/144[Principle: "everything is a model" / "everything is a node" #144]] +:fn-org145: footnote:org145[https://github.com/LIonWeb-org/organization/issues/145[Is `Language.dependsOn` a `UsedLanguage`? #145]] +:fn-org146: footnote:org146[https://github.com/LIonWeb-org/organization/issues/146[Rework NamespaceProvider and NamespacedEntity in M3 #146]] +:fn-org147: footnote:org147[https://github.com/LIonWeb-org/organization/issues/147[Rename LanguageElement to LanguageEntity #147]] +:fn-org148: footnote:org148[https://github.com/LIonWeb-org/organization/issues/148[Level of detail on API specifications #148]] +:fn-org149: footnote:org149[https://github.com/LIonWeb-org/organization/issues/149[Don't specify minimum supported range for integer #149]] \ No newline at end of file diff --git a/lioncore/metametamodel.puml b/lioncore/metametamodel.puml deleted file mode 100644 index 5ee95da..0000000 --- a/lioncore/metametamodel.puml +++ /dev/null @@ -1,76 +0,0 @@ -@startuml -hide empty members - -class Concept #LightGreen extends FeaturesContainer { - abstract: Boolean -} - -class ConceptInterface #LightGreen extends FeaturesContainer - -class Containment #LightBlue extends Link - -abstract class DataType #LightPink extends LanguageElement - -class Enumeration #LightPink extends DataType implements NamespaceProvider - -class EnumerationLiteral #LightPink implements NamespacedEntity - -abstract class Feature #LightBlue implements NamespacedEntity { - optional: Boolean -} - -abstract class FeaturesContainer #LightGreen extends LanguageElement implements NamespaceProvider { - allFeatures(): List -} - -abstract class Link #LightBlue extends Feature { - multiple: Boolean -} - -class Language implements NamespaceProvider { - name: String - key: Id - version: Integer -} - -abstract class LanguageElement implements NamespacedEntity - -abstract class NamespacedEntity { - name: String - key: Id -} - -interface NamespaceProvider { - namespaceQualifier(): String -} - -class PrimitiveType #LightPink extends DataType - -class Property #LightBlue extends Feature - -class Reference #LightBlue extends Link - -' relations: - -Concept "*" -> "0..1" Concept: extends -Concept "*" --> "*" ConceptInterface: implements - -ConceptInterface "*" --> "*" ConceptInterface: extends - -EnumerationLiteral "*" -* "1" Enumeration : literals - -Feature "*" -* "1" FeaturesContainer: features - -Link "*" --> "1" FeaturesContainer: type - -Language "*" --> "*" Language: dependsOn -LanguageElement "*" -* "1" Language: elements - -Property "*" -> "1" DataType: type - -legend - <#LightGray,#LightGray>| <#LightBlue>Feature | - | <#LightGreen>Feature Container | - | <#LightPink>DataType | -end legend -@enduml diff --git a/lioncore/metametamodel/builtins.json b/lioncore/metametamodel/builtins.json new file mode 100644 index 0000000..2d94817 --- /dev/null +++ b/lioncore/metametamodel/builtins.json @@ -0,0 +1,360 @@ +{ + "serializationFormatVersion": "1", + "languages": [ + { + "key": "LIonCore-M3", + "version": "1" + } + ], + "nodes": [ + { + "id": "LIonCore-builtins", + "concept": { + "language": "LIonCore-M3", + "version": "1", + "key": "Language" + }, + "properties": [ + { + "property": { + "language": "LIonCore-builtins", + "version": "1", + "key": "LIonCore-builtins-INamed-name" + }, + "value": "LIonCore.builtins" + }, + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "Language-version" + }, + "value": "1" + }, + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "IKeyed-key" + }, + "value": "LIonCore-builtins" + } + ], + "children": [ + { + "containment": { + "language": "LIonCore-M3", + "version": "1", + "key": "Language-entities" + }, + "children": [ + "LIonCore-builtins-String", + "LIonCore-builtins-Boolean", + "LIonCore-builtins-Integer", + "LIonCore-builtins-JSON", + "LIonCore-builtins-Node", + "LIonCore-builtins-INamed" + ] + } + ], + "references": [ + { + "reference": { + "language": "LIonCore-M3", + "version": "1", + "key": "Language-dependsOn" + }, + "targets": [] + } + ], + "parent": null + }, + { + "id": "LIonCore-builtins-String", + "concept": { + "language": "LIonCore-M3", + "version": "1", + "key": "PrimitiveType" + }, + "properties": [ + { + "property": { + "language": "LIonCore-builtins", + "version": "1", + "key": "LIonCore-builtins-INamed-name" + }, + "value": "String" + }, + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "IKeyed-key" + }, + "value": "LIonCore-builtins-String" + } + ], + "children": [], + "references": [], + "parent": "LIonCore-builtins" + }, + { + "id": "LIonCore-builtins-Boolean", + "concept": { + "language": "LIonCore-M3", + "version": "1", + "key": "PrimitiveType" + }, + "properties": [ + { + "property": { + "language": "LIonCore-builtins", + "version": "1", + "key": "LIonCore-builtins-INamed-name" + }, + "value": "Boolean" + }, + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "IKeyed-key" + }, + "value": "LIonCore-builtins-Boolean" + } + ], + "children": [], + "references": [], + "parent": "LIonCore-builtins" + }, + { + "id": "LIonCore-builtins-Integer", + "concept": { + "language": "LIonCore-M3", + "version": "1", + "key": "PrimitiveType" + }, + "properties": [ + { + "property": { + "language": "LIonCore-builtins", + "version": "1", + "key": "LIonCore-builtins-INamed-name" + }, + "value": "Integer" + }, + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "IKeyed-key" + }, + "value": "LIonCore-builtins-Integer" + } + ], + "children": [], + "references": [], + "parent": "LIonCore-builtins" + }, + { + "id": "LIonCore-builtins-JSON", + "concept": { + "language": "LIonCore-M3", + "version": "1", + "key": "PrimitiveType" + }, + "properties": [ + { + "property": { + "language": "LIonCore-builtins", + "version": "1", + "key": "LIonCore-builtins-INamed-name" + }, + "value": "JSON" + }, + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "IKeyed-key" + }, + "value": "LIonCore-builtins-JSON" + } + ], + "children": [], + "references": [], + "parent": "LIonCore-builtins" + }, + { + "id": "LIonCore-builtins-Node", + "concept": { + "language": "LIonCore-M3", + "version": "1", + "key": "Concept" + }, + "properties": [ + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "Concept-abstract" + }, + "value": "true" + }, + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "Concept-partition" + }, + "value": "false" + }, + { + "property": { + "language": "LIonCore-builtins", + "version": "1", + "key": "LIonCore-builtins-INamed-name" + }, + "value": "Node" + }, + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "IKeyed-key" + }, + "value": "LIonCore-builtins-Node" + } + ], + "children": [ + { + "containment": { + "language": "LIonCore-M3", + "version": "1", + "key": "Classifier-features" + }, + "children": [] + } + ], + "references": [ + { + "reference": { + "language": "LIonCore-M3", + "version": "1", + "key": "Concept-extends" + }, + "targets": [] + }, + { + "reference": { + "language": "LIonCore-M3", + "version": "1", + "key": "Concept-implements" + }, + "targets": [] + } + ], + "parent": "LIonCore-builtins" + }, + { + "id": "LIonCore-builtins-INamed", + "concept": { + "language": "LIonCore-M3", + "version": "1", + "key": "ConceptInterface" + }, + "properties": [ + { + "property": { + "language": "LIonCore-builtins", + "version": "1", + "key": "LIonCore-builtins-INamed-name" + }, + "value": "INamed" + }, + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "IKeyed-key" + }, + "value": "LIonCore-builtins-INamed" + } + ], + "children": [ + { + "containment": { + "language": "LIonCore-M3", + "version": "1", + "key": "Classifier-features" + }, + "children": [ + "LIonCore-builtins-INamed-name" + ] + } + ], + "references": [ + { + "reference": { + "language": "LIonCore-M3", + "version": "1", + "key": "ConceptInterface-extends" + }, + "targets": [] + } + ], + "parent": "LIonCore-builtins" + }, + { + "id": "LIonCore-builtins-INamed-name", + "concept": { + "language": "LIonCore-M3", + "version": "1", + "key": "Property" + }, + "properties": [ + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "Feature-optional" + }, + "value": "false" + }, + { + "property": { + "language": "LIonCore-builtins", + "version": "1", + "key": "LIonCore-builtins-INamed-name" + }, + "value": "name" + }, + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "IKeyed-key" + }, + "value": "LIonCore-builtins-INamed-name" + } + ], + "children": [], + "references": [ + { + "reference": { + "language": "LIonCore-M3", + "version": "1", + "key": "Property-type" + }, + "targets": [ + { + "resolveInfo": "String", + "reference": "LIonCore-builtins-String" + } + ] + } + ], + "parent": "LIonCore-builtins-INamed" + } + ] +} \ No newline at end of file diff --git a/lioncore/images/EcoreRelations.png b/lioncore/metametamodel/images/EcoreRelations.png similarity index 100% rename from lioncore/images/EcoreRelations.png rename to lioncore/metametamodel/images/EcoreRelations.png diff --git a/lioncore/images/LionWeb-Language-Example.png b/lioncore/metametamodel/images/LionWeb-Language-Example.png similarity index 100% rename from lioncore/images/LionWeb-Language-Example.png rename to lioncore/metametamodel/images/LionWeb-Language-Example.png diff --git a/lioncore/images/mps-structure-language.png b/lioncore/metametamodel/images/mps-structure-language.png similarity index 100% rename from lioncore/images/mps-structure-language.png rename to lioncore/metametamodel/images/mps-structure-language.png diff --git a/lioncore/metametamodel/lioncore.json b/lioncore/metametamodel/lioncore.json new file mode 100644 index 0000000..f15fbd2 --- /dev/null +++ b/lioncore/metametamodel/lioncore.json @@ -0,0 +1,2059 @@ +{ + "serializationFormatVersion": "1", + "languages": [ + { + "key": "LIonCore-M3", + "version": "1" + } + ], + "nodes": [ + { + "id": "-id-LIonCore-M3", + "concept": { + "language": "LIonCore-M3", + "version": "1", + "key": "Language" + }, + "properties": [ + { + "property": { + "language": "LIonCore-builtins", + "version": "1", + "key": "LIonCore-builtins-INamed-name" + }, + "value": "LIonCore.M3" + }, + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "Language-version" + }, + "value": "1" + }, + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "IKeyed-key" + }, + "value": "LIonCore-M3" + } + ], + "children": [ + { + "containment": { + "language": "LIonCore-M3", + "version": "1", + "key": "Language-entities" + }, + "children": [ + "-id-Concept", + "-id-ConceptInterface", + "-id-Containment", + "-id-DataType", + "-id-Enumeration", + "-id-EnumerationLiteral", + "-id-Feature", + "-id-Classifier", + "-id-Link", + "-id-Language", + "-id-LanguageEntity", + "-id-IKeyed", + "-id-PrimitiveType", + "-id-Property", + "-id-Reference" + ] + } + ], + "references": [ + { + "reference": { + "language": "LIonCore-M3", + "version": "1", + "key": "Language-dependsOn" + }, + "targets": [] + } + ], + "parent": null + }, + { + "id": "-id-Concept", + "concept": { + "language": "LIonCore-M3", + "version": "1", + "key": "Concept" + }, + "properties": [ + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "Concept-abstract" + }, + "value": "false" + }, + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "Concept-partition" + }, + "value": "false" + }, + { + "property": { + "language": "LIonCore-builtins", + "version": "1", + "key": "LIonCore-builtins-INamed-name" + }, + "value": "Concept" + }, + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "IKeyed-key" + }, + "value": "Concept" + } + ], + "children": [ + { + "containment": { + "language": "LIonCore-M3", + "version": "1", + "key": "Classifier-features" + }, + "children": [ + "-id-Concept-abstract", + "-id-Concept-partition", + "-id-Concept-extends", + "-id-Concept-implements" + ] + } + ], + "references": [ + { + "reference": { + "language": "LIonCore-M3", + "version": "1", + "key": "Concept-extends" + }, + "targets": [ + { + "resolveInfo": "Classifier", + "reference": "-id-Classifier" + } + ] + }, + { + "reference": { + "language": "LIonCore-M3", + "version": "1", + "key": "Concept-implements" + }, + "targets": [] + } + ], + "parent": "-id-LIonCore-M3" + }, + { + "id": "-id-Concept-abstract", + "concept": { + "language": "LIonCore-M3", + "version": "1", + "key": "Property" + }, + "properties": [ + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "Feature-optional" + }, + "value": "false" + }, + { + "property": { + "language": "LIonCore-builtins", + "version": "1", + "key": "LIonCore-builtins-INamed-name" + }, + "value": "abstract" + }, + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "IKeyed-key" + }, + "value": "Concept-abstract" + } + ], + "children": [], + "references": [ + { + "reference": { + "language": "LIonCore-M3", + "version": "1", + "key": "Property-type" + }, + "targets": [ + { + "resolveInfo": "Boolean", + "reference": "LIonCore-builtins-Boolean" + } + ] + } + ], + "parent": "-id-Concept" + }, + { + "id": "-id-Concept-extends", + "concept": { + "language": "LIonCore-M3", + "version": "1", + "key": "Reference" + }, + "properties": [ + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "Link-multiple" + }, + "value": "false" + }, + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "Feature-optional" + }, + "value": "true" + }, + { + "property": { + "language": "LIonCore-builtins", + "version": "1", + "key": "LIonCore-builtins-INamed-name" + }, + "value": "extends" + }, + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "IKeyed-key" + }, + "value": "Concept-extends" + } + ], + "children": [], + "references": [ + { + "reference": { + "language": "LIonCore-M3", + "version": "1", + "key": "Link-type" + }, + "targets": [ + { + "resolveInfo": "Concept", + "reference": "-id-Concept" + } + ] + } + ], + "parent": "-id-Concept" + }, + { + "id": "-id-Concept-implements", + "concept": { + "language": "LIonCore-M3", + "version": "1", + "key": "Reference" + }, + "properties": [ + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "Link-multiple" + }, + "value": "true" + }, + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "Feature-optional" + }, + "value": "true" + }, + { + "property": { + "language": "LIonCore-builtins", + "version": "1", + "key": "LIonCore-builtins-INamed-name" + }, + "value": "implements" + }, + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "IKeyed-key" + }, + "value": "Concept-implements" + } + ], + "children": [], + "references": [ + { + "reference": { + "language": "LIonCore-M3", + "version": "1", + "key": "Link-type" + }, + "targets": [ + { + "resolveInfo": "ConceptInterface", + "reference": "-id-ConceptInterface" + } + ] + } + ], + "parent": "-id-Concept" + }, + { + "id": "-id-Concept-partition", + "concept": { + "language": "LIonCore-M3", + "version": "1", + "key": "Property" + }, + "properties": [ + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "Feature-optional" + }, + "value": "false" + }, + { + "property": { + "language": "LIonCore-builtins", + "version": "1", + "key": "LIonCore-builtins-INamed-name" + }, + "value": "partition" + }, + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "IKeyed-key" + }, + "value": "Concept-partition" + } + ], + "children": [], + "references": [ + { + "reference": { + "language": "LIonCore-M3", + "version": "1", + "key": "Property-type" + }, + "targets": [ + { + "resolveInfo": "Boolean", + "reference": "LIonCore-builtins-Boolean" + } + ] + } + ], + "parent": "-id-Concept" + }, + { + "id": "-id-ConceptInterface", + "concept": { + "language": "LIonCore-M3", + "version": "1", + "key": "Concept" + }, + "properties": [ + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "Concept-abstract" + }, + "value": "false" + }, + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "Concept-partition" + }, + "value": "false" + }, + { + "property": { + "language": "LIonCore-builtins", + "version": "1", + "key": "LIonCore-builtins-INamed-name" + }, + "value": "ConceptInterface" + }, + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "IKeyed-key" + }, + "value": "ConceptInterface" + } + ], + "children": [ + { + "containment": { + "language": "LIonCore-M3", + "version": "1", + "key": "Classifier-features" + }, + "children": [ + "-id-ConceptInterface-extends" + ] + } + ], + "references": [ + { + "reference": { + "language": "LIonCore-M3", + "version": "1", + "key": "Concept-extends" + }, + "targets": [ + { + "resolveInfo": "Classifier", + "reference": "-id-Classifier" + } + ] + }, + { + "reference": { + "language": "LIonCore-M3", + "version": "1", + "key": "Concept-implements" + }, + "targets": [] + } + ], + "parent": "-id-LIonCore-M3" + }, + { + "id": "-id-ConceptInterface-extends", + "concept": { + "language": "LIonCore-M3", + "version": "1", + "key": "Reference" + }, + "properties": [ + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "Link-multiple" + }, + "value": "true" + }, + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "Feature-optional" + }, + "value": "true" + }, + { + "property": { + "language": "LIonCore-builtins", + "version": "1", + "key": "LIonCore-builtins-INamed-name" + }, + "value": "extends" + }, + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "IKeyed-key" + }, + "value": "ConceptInterface-extends" + } + ], + "children": [], + "references": [ + { + "reference": { + "language": "LIonCore-M3", + "version": "1", + "key": "Link-type" + }, + "targets": [ + { + "resolveInfo": "ConceptInterface", + "reference": "-id-ConceptInterface" + } + ] + } + ], + "parent": "-id-ConceptInterface" + }, + { + "id": "-id-Containment", + "concept": { + "language": "LIonCore-M3", + "version": "1", + "key": "Concept" + }, + "properties": [ + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "Concept-abstract" + }, + "value": "false" + }, + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "Concept-partition" + }, + "value": "false" + }, + { + "property": { + "language": "LIonCore-builtins", + "version": "1", + "key": "LIonCore-builtins-INamed-name" + }, + "value": "Containment" + }, + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "IKeyed-key" + }, + "value": "Containment" + } + ], + "children": [ + { + "containment": { + "language": "LIonCore-M3", + "version": "1", + "key": "Classifier-features" + }, + "children": [] + } + ], + "references": [ + { + "reference": { + "language": "LIonCore-M3", + "version": "1", + "key": "Concept-extends" + }, + "targets": [ + { + "resolveInfo": "Link", + "reference": "-id-Link" + } + ] + }, + { + "reference": { + "language": "LIonCore-M3", + "version": "1", + "key": "Concept-implements" + }, + "targets": [] + } + ], + "parent": "-id-LIonCore-M3" + }, + { + "id": "-id-DataType", + "concept": { + "language": "LIonCore-M3", + "version": "1", + "key": "Concept" + }, + "properties": [ + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "Concept-abstract" + }, + "value": "true" + }, + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "Concept-partition" + }, + "value": "false" + }, + { + "property": { + "language": "LIonCore-builtins", + "version": "1", + "key": "LIonCore-builtins-INamed-name" + }, + "value": "DataType" + }, + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "IKeyed-key" + }, + "value": "DataType" + } + ], + "children": [ + { + "containment": { + "language": "LIonCore-M3", + "version": "1", + "key": "Classifier-features" + }, + "children": [] + } + ], + "references": [ + { + "reference": { + "language": "LIonCore-M3", + "version": "1", + "key": "Concept-extends" + }, + "targets": [ + { + "resolveInfo": "LanguageEntity", + "reference": "-id-LanguageEntity" + } + ] + }, + { + "reference": { + "language": "LIonCore-M3", + "version": "1", + "key": "Concept-implements" + }, + "targets": [] + } + ], + "parent": "-id-LIonCore-M3" + }, + { + "id": "-id-Enumeration", + "concept": { + "language": "LIonCore-M3", + "version": "1", + "key": "Concept" + }, + "properties": [ + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "Concept-abstract" + }, + "value": "false" + }, + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "Concept-partition" + }, + "value": "false" + }, + { + "property": { + "language": "LIonCore-builtins", + "version": "1", + "key": "LIonCore-builtins-INamed-name" + }, + "value": "Enumeration" + }, + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "IKeyed-key" + }, + "value": "Enumeration" + } + ], + "children": [ + { + "containment": { + "language": "LIonCore-M3", + "version": "1", + "key": "Classifier-features" + }, + "children": [ + "-id-Enumeration-literals" + ] + } + ], + "references": [ + { + "reference": { + "language": "LIonCore-M3", + "version": "1", + "key": "Concept-extends" + }, + "targets": [ + { + "resolveInfo": "DataType", + "reference": "-id-DataType" + } + ] + }, + { + "reference": { + "language": "LIonCore-M3", + "version": "1", + "key": "Concept-implements" + }, + "targets": [] + } + ], + "parent": "-id-LIonCore-M3" + }, + { + "id": "-id-Enumeration-literals", + "concept": { + "language": "LIonCore-M3", + "version": "1", + "key": "Containment" + }, + "properties": [ + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "Link-multiple" + }, + "value": "true" + }, + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "Feature-optional" + }, + "value": "true" + }, + { + "property": { + "language": "LIonCore-builtins", + "version": "1", + "key": "LIonCore-builtins-INamed-name" + }, + "value": "literals" + }, + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "IKeyed-key" + }, + "value": "Enumeration-literals" + } + ], + "children": [], + "references": [ + { + "reference": { + "language": "LIonCore-M3", + "version": "1", + "key": "Link-type" + }, + "targets": [ + { + "resolveInfo": "EnumerationLiteral", + "reference": "-id-EnumerationLiteral" + } + ] + } + ], + "parent": "-id-Enumeration" + }, + { + "id": "-id-EnumerationLiteral", + "concept": { + "language": "LIonCore-M3", + "version": "1", + "key": "Concept" + }, + "properties": [ + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "Concept-abstract" + }, + "value": "false" + }, + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "Concept-partition" + }, + "value": "false" + }, + { + "property": { + "language": "LIonCore-builtins", + "version": "1", + "key": "LIonCore-builtins-INamed-name" + }, + "value": "EnumerationLiteral" + }, + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "IKeyed-key" + }, + "value": "EnumerationLiteral" + } + ], + "children": [ + { + "containment": { + "language": "LIonCore-M3", + "version": "1", + "key": "Classifier-features" + }, + "children": [] + } + ], + "references": [ + { + "reference": { + "language": "LIonCore-M3", + "version": "1", + "key": "Concept-extends" + }, + "targets": [] + }, + { + "reference": { + "language": "LIonCore-M3", + "version": "1", + "key": "Concept-implements" + }, + "targets": [ + { + "resolveInfo": "IKeyed", + "reference": "-id-IKeyed" + } + ] + } + ], + "parent": "-id-LIonCore-M3" + }, + { + "id": "-id-Feature", + "concept": { + "language": "LIonCore-M3", + "version": "1", + "key": "Concept" + }, + "properties": [ + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "Concept-abstract" + }, + "value": "true" + }, + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "Concept-partition" + }, + "value": "false" + }, + { + "property": { + "language": "LIonCore-builtins", + "version": "1", + "key": "LIonCore-builtins-INamed-name" + }, + "value": "Feature" + }, + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "IKeyed-key" + }, + "value": "Feature" + } + ], + "children": [ + { + "containment": { + "language": "LIonCore-M3", + "version": "1", + "key": "Classifier-features" + }, + "children": [ + "-id-Feature-optional" + ] + } + ], + "references": [ + { + "reference": { + "language": "LIonCore-M3", + "version": "1", + "key": "Concept-extends" + }, + "targets": [] + }, + { + "reference": { + "language": "LIonCore-M3", + "version": "1", + "key": "Concept-implements" + }, + "targets": [ + { + "resolveInfo": "IKeyed", + "reference": "-id-IKeyed" + } + ] + } + ], + "parent": "-id-LIonCore-M3" + }, + { + "id": "-id-Feature-optional", + "concept": { + "language": "LIonCore-M3", + "version": "1", + "key": "Property" + }, + "properties": [ + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "Feature-optional" + }, + "value": "false" + }, + { + "property": { + "language": "LIonCore-builtins", + "version": "1", + "key": "LIonCore-builtins-INamed-name" + }, + "value": "optional" + }, + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "IKeyed-key" + }, + "value": "Feature-optional" + } + ], + "children": [], + "references": [ + { + "reference": { + "language": "LIonCore-M3", + "version": "1", + "key": "Property-type" + }, + "targets": [ + { + "resolveInfo": "Boolean", + "reference": "LIonCore-builtins-Boolean" + } + ] + } + ], + "parent": "-id-Feature" + }, + { + "id": "-id-Classifier", + "concept": { + "language": "LIonCore-M3", + "version": "1", + "key": "Concept" + }, + "properties": [ + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "Concept-abstract" + }, + "value": "true" + }, + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "Concept-partition" + }, + "value": "false" + }, + { + "property": { + "language": "LIonCore-builtins", + "version": "1", + "key": "LIonCore-builtins-INamed-name" + }, + "value": "Classifier" + }, + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "IKeyed-key" + }, + "value": "Classifier" + } + ], + "children": [ + { + "containment": { + "language": "LIonCore-M3", + "version": "1", + "key": "Classifier-features" + }, + "children": [ + "-id-Classifier-features" + ] + } + ], + "references": [ + { + "reference": { + "language": "LIonCore-M3", + "version": "1", + "key": "Concept-extends" + }, + "targets": [ + { + "resolveInfo": "LanguageEntity", + "reference": "-id-LanguageEntity" + } + ] + }, + { + "reference": { + "language": "LIonCore-M3", + "version": "1", + "key": "Concept-implements" + }, + "targets": [] + } + ], + "parent": "-id-LIonCore-M3" + }, + { + "id": "-id-Classifier-features", + "concept": { + "language": "LIonCore-M3", + "version": "1", + "key": "Containment" + }, + "properties": [ + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "Link-multiple" + }, + "value": "true" + }, + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "Feature-optional" + }, + "value": "true" + }, + { + "property": { + "language": "LIonCore-builtins", + "version": "1", + "key": "LIonCore-builtins-INamed-name" + }, + "value": "features" + }, + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "IKeyed-key" + }, + "value": "Classifier-features" + } + ], + "children": [], + "references": [ + { + "reference": { + "language": "LIonCore-M3", + "version": "1", + "key": "Link-type" + }, + "targets": [ + { + "resolveInfo": "Feature", + "reference": "-id-Feature" + } + ] + } + ], + "parent": "-id-Classifier" + }, + { + "id": "-id-Link", + "concept": { + "language": "LIonCore-M3", + "version": "1", + "key": "Concept" + }, + "properties": [ + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "Concept-abstract" + }, + "value": "true" + }, + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "Concept-partition" + }, + "value": "false" + }, + { + "property": { + "language": "LIonCore-builtins", + "version": "1", + "key": "LIonCore-builtins-INamed-name" + }, + "value": "Link" + }, + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "IKeyed-key" + }, + "value": "Link" + } + ], + "children": [ + { + "containment": { + "language": "LIonCore-M3", + "version": "1", + "key": "Classifier-features" + }, + "children": [ + "-id-Link-multiple", + "-id-Link-type" + ] + } + ], + "references": [ + { + "reference": { + "language": "LIonCore-M3", + "version": "1", + "key": "Concept-extends" + }, + "targets": [ + { + "resolveInfo": "Feature", + "reference": "-id-Feature" + } + ] + }, + { + "reference": { + "language": "LIonCore-M3", + "version": "1", + "key": "Concept-implements" + }, + "targets": [] + } + ], + "parent": "-id-LIonCore-M3" + }, + { + "id": "-id-Link-multiple", + "concept": { + "language": "LIonCore-M3", + "version": "1", + "key": "Property" + }, + "properties": [ + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "Feature-optional" + }, + "value": "false" + }, + { + "property": { + "language": "LIonCore-builtins", + "version": "1", + "key": "LIonCore-builtins-INamed-name" + }, + "value": "multiple" + }, + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "IKeyed-key" + }, + "value": "Link-multiple" + } + ], + "children": [], + "references": [ + { + "reference": { + "language": "LIonCore-M3", + "version": "1", + "key": "Property-type" + }, + "targets": [ + { + "resolveInfo": "Boolean", + "reference": "LIonCore-builtins-Boolean" + } + ] + } + ], + "parent": "-id-Link" + }, + { + "id": "-id-Link-type", + "concept": { + "language": "LIonCore-M3", + "version": "1", + "key": "Reference" + }, + "properties": [ + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "Link-multiple" + }, + "value": "false" + }, + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "Feature-optional" + }, + "value": "false" + }, + { + "property": { + "language": "LIonCore-builtins", + "version": "1", + "key": "LIonCore-builtins-INamed-name" + }, + "value": "type" + }, + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "IKeyed-key" + }, + "value": "Link-type" + } + ], + "children": [], + "references": [ + { + "reference": { + "language": "LIonCore-M3", + "version": "1", + "key": "Link-type" + }, + "targets": [ + { + "resolveInfo": "Classifier", + "reference": "-id-Classifier" + } + ] + } + ], + "parent": "-id-Link" + }, + { + "id": "-id-Language", + "concept": { + "language": "LIonCore-M3", + "version": "1", + "key": "Concept" + }, + "properties": [ + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "Concept-abstract" + }, + "value": "false" + }, + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "Concept-partition" + }, + "value": "true" + }, + { + "property": { + "language": "LIonCore-builtins", + "version": "1", + "key": "LIonCore-builtins-INamed-name" + }, + "value": "Language" + }, + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "IKeyed-key" + }, + "value": "Language" + } + ], + "children": [ + { + "containment": { + "language": "LIonCore-M3", + "version": "1", + "key": "Classifier-features" + }, + "children": [ + "-id-Language-version", + "-id-Language-dependsOn", + "-id-Language-entities" + ] + } + ], + "references": [ + { + "reference": { + "language": "LIonCore-M3", + "version": "1", + "key": "Concept-extends" + }, + "targets": [] + }, + { + "reference": { + "language": "LIonCore-M3", + "version": "1", + "key": "Concept-implements" + }, + "targets": [ + { + "resolveInfo": "IKeyed", + "reference": "-id-IKeyed" + } + ] + } + ], + "parent": "-id-LIonCore-M3" + }, + { + "id": "-id-Language-dependsOn", + "concept": { + "language": "LIonCore-M3", + "version": "1", + "key": "Reference" + }, + "properties": [ + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "Link-multiple" + }, + "value": "true" + }, + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "Feature-optional" + }, + "value": "true" + }, + { + "property": { + "language": "LIonCore-builtins", + "version": "1", + "key": "LIonCore-builtins-INamed-name" + }, + "value": "dependsOn" + }, + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "IKeyed-key" + }, + "value": "Language-dependsOn" + } + ], + "children": [], + "references": [ + { + "reference": { + "language": "LIonCore-M3", + "version": "1", + "key": "Link-type" + }, + "targets": [ + { + "resolveInfo": "Language", + "reference": "-id-Language" + } + ] + } + ], + "parent": "-id-Language" + }, + { + "id": "-id-Language-entities", + "concept": { + "language": "LIonCore-M3", + "version": "1", + "key": "Containment" + }, + "properties": [ + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "Link-multiple" + }, + "value": "true" + }, + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "Feature-optional" + }, + "value": "true" + }, + { + "property": { + "language": "LIonCore-builtins", + "version": "1", + "key": "LIonCore-builtins-INamed-name" + }, + "value": "entities" + }, + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "IKeyed-key" + }, + "value": "Language-entities" + } + ], + "children": [], + "references": [ + { + "reference": { + "language": "LIonCore-M3", + "version": "1", + "key": "Link-type" + }, + "targets": [ + { + "resolveInfo": "LanguageEntity", + "reference": "-id-LanguageEntity" + } + ] + } + ], + "parent": "-id-Language" + }, + { + "id": "-id-Language-version", + "concept": { + "language": "LIonCore-M3", + "version": "1", + "key": "Property" + }, + "properties": [ + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "Feature-optional" + }, + "value": "false" + }, + { + "property": { + "language": "LIonCore-builtins", + "version": "1", + "key": "LIonCore-builtins-INamed-name" + }, + "value": "version" + }, + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "IKeyed-key" + }, + "value": "Language-version" + } + ], + "children": [], + "references": [ + { + "reference": { + "language": "LIonCore-M3", + "version": "1", + "key": "Property-type" + }, + "targets": [ + { + "resolveInfo": "String", + "reference": "LIonCore-builtins-String" + } + ] + } + ], + "parent": "-id-Language" + }, + { + "id": "-id-LanguageEntity", + "concept": { + "language": "LIonCore-M3", + "version": "1", + "key": "Concept" + }, + "properties": [ + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "Concept-abstract" + }, + "value": "true" + }, + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "Concept-partition" + }, + "value": "false" + }, + { + "property": { + "language": "LIonCore-builtins", + "version": "1", + "key": "LIonCore-builtins-INamed-name" + }, + "value": "LanguageEntity" + }, + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "IKeyed-key" + }, + "value": "LanguageEntity" + } + ], + "children": [ + { + "containment": { + "language": "LIonCore-M3", + "version": "1", + "key": "Classifier-features" + }, + "children": [] + } + ], + "references": [ + { + "reference": { + "language": "LIonCore-M3", + "version": "1", + "key": "Concept-extends" + }, + "targets": [] + }, + { + "reference": { + "language": "LIonCore-M3", + "version": "1", + "key": "Concept-implements" + }, + "targets": [ + { + "resolveInfo": "IKeyed", + "reference": "-id-IKeyed" + } + ] + } + ], + "parent": "-id-LIonCore-M3" + }, + { + "id": "-id-IKeyed", + "concept": { + "language": "LIonCore-M3", + "version": "1", + "key": "ConceptInterface" + }, + "properties": [ + { + "property": { + "language": "LIonCore-builtins", + "version": "1", + "key": "LIonCore-builtins-INamed-name" + }, + "value": "IKeyed" + }, + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "IKeyed-key" + }, + "value": "IKeyed" + } + ], + "children": [ + { + "containment": { + "language": "LIonCore-M3", + "version": "1", + "key": "Classifier-features" + }, + "children": [ + "-id-IKeyed-key" + ] + } + ], + "references": [ + { + "reference": { + "language": "LIonCore-M3", + "version": "1", + "key": "ConceptInterface-extends" + }, + "targets": [ + { + "resolveInfo": "INamed", + "reference": "LIonCore-builtins-INamed" + } + ] + } + ], + "parent": "-id-LIonCore-M3" + }, + { + "id": "-id-IKeyed-key", + "concept": { + "language": "LIonCore-M3", + "version": "1", + "key": "Property" + }, + "properties": [ + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "Feature-optional" + }, + "value": "false" + }, + { + "property": { + "language": "LIonCore-builtins", + "version": "1", + "key": "LIonCore-builtins-INamed-name" + }, + "value": "key" + }, + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "IKeyed-key" + }, + "value": "IKeyed-key" + } + ], + "children": [], + "references": [ + { + "reference": { + "language": "LIonCore-M3", + "version": "1", + "key": "Property-type" + }, + "targets": [ + { + "resolveInfo": "String", + "reference": "LIonCore-builtins-String" + } + ] + } + ], + "parent": "-id-IKeyed" + }, + { + "id": "-id-PrimitiveType", + "concept": { + "language": "LIonCore-M3", + "version": "1", + "key": "Concept" + }, + "properties": [ + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "Concept-abstract" + }, + "value": "false" + }, + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "Concept-partition" + }, + "value": "false" + }, + { + "property": { + "language": "LIonCore-builtins", + "version": "1", + "key": "LIonCore-builtins-INamed-name" + }, + "value": "PrimitiveType" + }, + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "IKeyed-key" + }, + "value": "PrimitiveType" + } + ], + "children": [ + { + "containment": { + "language": "LIonCore-M3", + "version": "1", + "key": "Classifier-features" + }, + "children": [] + } + ], + "references": [ + { + "reference": { + "language": "LIonCore-M3", + "version": "1", + "key": "Concept-extends" + }, + "targets": [ + { + "resolveInfo": "DataType", + "reference": "-id-DataType" + } + ] + }, + { + "reference": { + "language": "LIonCore-M3", + "version": "1", + "key": "Concept-implements" + }, + "targets": [] + } + ], + "parent": "-id-LIonCore-M3" + }, + { + "id": "-id-Property", + "concept": { + "language": "LIonCore-M3", + "version": "1", + "key": "Concept" + }, + "properties": [ + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "Concept-abstract" + }, + "value": "false" + }, + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "Concept-partition" + }, + "value": "false" + }, + { + "property": { + "language": "LIonCore-builtins", + "version": "1", + "key": "LIonCore-builtins-INamed-name" + }, + "value": "Property" + }, + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "IKeyed-key" + }, + "value": "Property" + } + ], + "children": [ + { + "containment": { + "language": "LIonCore-M3", + "version": "1", + "key": "Classifier-features" + }, + "children": [ + "-id-Property-type" + ] + } + ], + "references": [ + { + "reference": { + "language": "LIonCore-M3", + "version": "1", + "key": "Concept-extends" + }, + "targets": [ + { + "resolveInfo": "Feature", + "reference": "-id-Feature" + } + ] + }, + { + "reference": { + "language": "LIonCore-M3", + "version": "1", + "key": "Concept-implements" + }, + "targets": [] + } + ], + "parent": "-id-LIonCore-M3" + }, + { + "id": "-id-Property-type", + "concept": { + "language": "LIonCore-M3", + "version": "1", + "key": "Reference" + }, + "properties": [ + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "Link-multiple" + }, + "value": "false" + }, + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "Feature-optional" + }, + "value": "false" + }, + { + "property": { + "language": "LIonCore-builtins", + "version": "1", + "key": "LIonCore-builtins-INamed-name" + }, + "value": "type" + }, + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "IKeyed-key" + }, + "value": "Property-type" + } + ], + "children": [], + "references": [ + { + "reference": { + "language": "LIonCore-M3", + "version": "1", + "key": "Link-type" + }, + "targets": [ + { + "resolveInfo": "DataType", + "reference": "-id-DataType" + } + ] + } + ], + "parent": "-id-Property" + }, + { + "id": "-id-Reference", + "concept": { + "language": "LIonCore-M3", + "version": "1", + "key": "Concept" + }, + "properties": [ + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "Concept-abstract" + }, + "value": "false" + }, + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "Concept-partition" + }, + "value": "false" + }, + { + "property": { + "language": "LIonCore-builtins", + "version": "1", + "key": "LIonCore-builtins-INamed-name" + }, + "value": "Reference" + }, + { + "property": { + "language": "LIonCore-M3", + "version": "1", + "key": "IKeyed-key" + }, + "value": "Reference" + } + ], + "children": [ + { + "containment": { + "language": "LIonCore-M3", + "version": "1", + "key": "Classifier-features" + }, + "children": [] + } + ], + "references": [ + { + "reference": { + "language": "LIonCore-M3", + "version": "1", + "key": "Concept-extends" + }, + "targets": [ + { + "resolveInfo": "Link", + "reference": "-id-Link" + } + ] + }, + { + "reference": { + "language": "LIonCore-M3", + "version": "1", + "key": "Concept-implements" + }, + "targets": [] + } + ], + "parent": "-id-LIonCore-M3" + } + ] +} \ No newline at end of file diff --git a/lioncore/metametamodel.adoc b/lioncore/metametamodel/metametamodel.adoc similarity index 67% rename from lioncore/metametamodel.adoc rename to lioncore/metametamodel/metametamodel.adoc index 27313af..6bd99f2 100644 --- a/lioncore/metametamodel.adoc +++ b/lioncore/metametamodel/metametamodel.adoc @@ -1,13 +1,13 @@ -include::issue-footnotes.adoc[] - +include::../issue-footnotes.adoc[] +:serialization: ../serialization/serialization = Meta-Metamodel :toc: preamble :toclevels: 3 :sectnums: -In this document we describe the Meta-Metamodel to be used by LionWeb. -The Meta-Metamodel is called LionCore. +In this document we describe the Meta-Metamodel to be used by LIonWeb. +The Meta-Metamodel is called LIonCore. [[goals]] == Goals @@ -59,7 +59,7 @@ The classes are <>, <>, <>, <> for <>. .Example For example, a Language for accounting could collect several Concepts such as _Invoice_, _Customer_, _InvoiceLine_, _Product_. @@ -78,24 +78,19 @@ EPackages have instead sub-packages and MPS Languages have virtual folders. For this use case, different Languages could be used instead. .Characteristics -A Language has a [[Language.name, Language.name]]`name`{fn-org77}, a [[Language.key, Language.key]]`key`{fn-org90}, and a [[Language.version, Language.version]]`version`{fn-org7}{fn-org92}, similar to MPS Languages. +A Language has a <>, a <>{fn-org90}, and a [[Language.version, Language.version]]`version`{fn-org7}{fn-org92}, similar to MPS Languages. -[[Language.elements, Language.elements]] -Each Language will contain a list of <> in its `elements` containment. +[[Language.entities, Language.entities]] +Each Language will contain a list of <> in its `entities` containment. -A Language is a <> (as it provides a Namespace to all its elements). +A Language is an <> (as it has a name) and an <> (as it has a key){fn-org142}. [[Language.dependsOn, Language.dependsOn]] -A Language can depend on other Languages via `dependsOn` reference. +A Language can depend on other Languages via `dependsOn` reference.{fn-org145} Dependencies must be explicitly declared.{fn-org50} .Constraints -``key``s must a valid <>. -`key` SHOULD be globally unique, and MUST be unique within an <>.{fn-org91} -For approximate global uniqueness, we SHOULD adopt Java's package naming scheme, based on domain names. -As we don't allow dots (`.`) in ids, we SHOULD use dashes (`-`) instead. - -`version` can be any non-empty string.{fn-org128}{fn-org130} +`version` can be any non-empty string.{fn-org130}{fn-org131} Language elements contained in a Language are allowed to refer to these other Language elements:{fn-org50} @@ -120,23 +115,26 @@ Single entities could be Concept instances, such as Invoice #1/2022. A Concept is roughly equivalent to an `EClass` (with the `isInterface` flag set to `false`) or an MPS’s `ConceptDeclaration`. .Characteristics -A Concept has a <> and an <>. +A Concept has a <> and an <>. [[Concept.abstract, Concept.abstract]] A Concept can be concrete (i.e., instantiable) or abstract, marked by boolean `abstract` property. -A Concept is a <> (as it has features). -It is indirectly a <> (as it is a top level element in a <>), a <> (as it has an identity, and it is contained in the namespace of the Language), and a <> (as it act as the namespace for its features). +[[Concept.partition, Concept.partition]] +A concept can be marked as <> via the boolean `partition` property.{fn-org29} + +A Concept is a <> (as it has features). +It is indirectly a <> (as it is a top level element in a <>), an <> (as it has a name), a <> (as it has a key). [[Concept.extends, Concept.extends]] Each Concept `extends` zero or one Concepts. -If no Concepts are explicitly extended, the Concept will implicitly extend the Concept named `Node`. +If no Concepts are explicitly extended, the Concept will implicitly extend the Concept <>. `Node` is the only concept that truly does not extend any Concept. [[Concept.implements, Concept.implements]] A Concept `implements` zero or more <>. -A Concept can have any number of <>, given it is a <>. +A Concept can have any number of <>, given it is a <>. .Constraints TBD @@ -152,15 +150,15 @@ For example, `Named` would be a ConceptInterface. A ConceptInterface in LionWeb will be roughly equivalent to an `EClass` (with the `isInterface` flag set to `true`) or an MPS’s `ConceptInterfaceDeclaration`. .Characteristics -A ConceptInterface has a <> and an <>. +A ConceptInterface has a <> and an <>. -A ConceptInterface is an <> (as it has features). -It is indirectly a <> (as it is a top level element in a <>), a <> (as it has an identity, and it is contained in the namespace of the Language), and a <> (as it act as the namespace for its features). +A ConceptInterface is an <> (as it has features). +It is indirectly a <> (as it is a top level element in a <>), an <> (as it has a name), a <> (as it has a key). [[ConceptInterface.extends, ConceptInterface.extends]] Each ConceptInterface `extends` zero or more ConceptInterfaces. -A ConceptInterface can have any number of <>, given it is a <>. +A ConceptInterface can have any number of <>, given it is a <>. .Constraints {empty} @@ -178,10 +176,10 @@ A PrimitiveType is similar to Ecore’s `EDataType` and to MPS’ `PrimitiveData Differently from ECore’s `EDataType` PrimitiveType has no flag `serializable`, and it does not inherit fields such as `instanceClassName`, `instanceClass`, or `defaultValue`. .Characteristics -A PrimitiveType has a <> and an <>. +A PrimitiveType has a <> and an <>. A PrimitiveType is a <> (as it can be used as <> of a <>). -It is indirectly a <> (as it is a top level element in a <>) and a <> (as it has an identity, and it is contained in the namespace of the Language). +It is indirectly a <> (as it is a top level element in a <>), an <> (as it has a name) and a <> (as it has a key). The correspondence between a PrimitiveType an implementation class on a specific platforms can be specified through annotations, but it is not specified on the PrimitiveType itself. @@ -201,13 +199,15 @@ An Enumeration is similar to Ecore’s `EEnum` and to MPS’ `EnumerationDeclara Differently from ECore’s `EEnum` Enumeration has no flag `serializable`, and it does not inherit fields such as `instanceClassName`, `instanceClass`, or `defaultValue`. .Characteristics -An Enumeration has a <> and an <>. +An Enumeration has a <> and an <>. [[Enumeration.literals, Enumeration.literals]] An Enumeration contains <> in its `literals` containment. +It also represents the <> for the EnumerationLiterals. -An Enumeration is a <> (as it can be used as <> of a <>) and a <> (as it act as the namespace for its literals). -It is indirectly a <> (as it is a top level element in a <>) and a <> (as it has an identity, and it is contained in the namespace of the Language). + +An Enumeration is a <> (as it can be used as <> of a <>). +It is indirectly a <> (as it is a top level element in a <>), an <> (as it has a name) and a <> (as it has a key). .Constraints TBD @@ -223,16 +223,18 @@ _Monday_, _Tuesday_, _Wednesday_, _Thursday_, _Friday_, _Saturday_ and _Sunday_ An EnumerationLiteral is similar to Ecore’s `EEnumLiteral` and to MPS’ `EnumerationMemberDeclaration`. .Characteristics -An EnumerationLiteral has a <> and an <>. +An EnumerationLiteral has a <> and an <>. -An Enumeration is a <> (as it has an identity, and it is contained in the namespace of its <>). +An Enumeration is a <> (as it has a key) and indirectly an <> (as it has a name). .Constraints -TBD +Each EnumerationLiteral must have a unique `name` within the Enumeration. + +Each EnumerationLiteral belongs to one and only one Enumeration. [[Containment]] ==== Containment -Represents a relation between a containing <> and a contained <>. +Represents a relation between a containing <> and a contained <>. .Example Between an _IfStatement_ and its _condition_ there is a Containment relation. @@ -245,20 +247,20 @@ A Containment is similar to an MPS’s `LinkDeclaration` with `metaClass` having Differently from a `LinkDeclaration` there is no field `unordered`. .Characteristics -A Containment has a <> and an <>. +A Containment has a <> and an <>. It can be marked as <> and <>. -A Containment refers its <>, which is a <>. +A Containment refers its <>, which is a <>. -A Containment is a <> (as it describes a relation between two FeaturesContainers). -It is indirectly a <> (as it describes the characteristics of a <>) and a <> (as it has an identity, and it is contained in the namespace of its FeaturesContainer). +A Containment is a <> (as it describes a relation between two Classifiers). +It is indirectly a <> (as it describes the characteristics of a <>), an <> (as it has a name) and a <> (as it has a key). .Constraints TBD [[Reference]] ==== Reference -Represents a relation between a referring <> and referred <>. +Represents a relation between a referring <> and referred <>. .Example _VariableReference_ may have a Reference to a _VariableDeclaration_. @@ -271,13 +273,13 @@ A Reference is similar to an MPS’s `LinkDeclaration` with `metaClass` having v Differently from a `LinkDeclaration` there is no field `unordered`. .Characteristics -A Reference has a <> and an <>. +A Reference has a <> and an <>. It can be marked as <> and <>. -A Containment refers its <>, which is a <>. +A Containment refers its <>, which is a <>. -A Reference is a <> (as it describes a relation between two FeaturesContainers). -It is indirectly a <> (as it describes the characteristics of a <>) and a <> (as it has an identity, and it is contained in the namespace of its FeaturesContainer). +A Reference is a <> (as it describes a relation between two Classifiers). +It is indirectly a <> (as it describes the characteristics of a <>), an <> (as it has a name) and a <> (as it has a key). .Constraints TBD @@ -295,109 +297,85 @@ A Property is similar to Ecore’s `EAttribute`. A Property is similar to MPS’s `AttributeDeclaration`. .Characteristics -A Property has a <> and an <>. +A Property has a <> and an <>. It can be marked as <>. [[Property.type, Property.type]] A Property refers its `type`, which is a <>. -A Property is a <> (as it describes the characteristics of a <>). -It is indirectly a <> (as it has an identity, and it is contained in the namespace of its FeaturesContainer). +A Property is a <> (as it describes the characteristics of a <>). +It is indirectly a <> (as it has a key) and an <> (as it has a name). .Constraints TBD === Abstract Classes -The abstract classes are <>, <>, <>, <>, <>, and <>. - -[[NamespacedEntity]] -==== NamespacedEntity -Something with a name and contained in a Namespace. - -.Example -A Concept _Invoice_, contained in a Language `com.foo.Accounting`. -Therefore, _Invoice_ will have the qualifiedName `com.foo.Accounting.Invoice`. - -.EMF & MPS equivalent -n/a - -.Characteristics -[[NamespacedEntity.name, NamespacedEntity.name]] -A NamespacedEntity has a `name`.{fn-org84} - -[[NamespacedEntity.key, NamespacedEntity.key]] -A NamespacedEntity has an `key`.{fn-org90} - -.Constraints -A NamespaceEntity's `name` must be unique within the NamespaceProvider. - -A NamespaceEntity's `key` must be unique within the Language.{fn-org91} -``key``s must a valid <>. - +The abstract classes are <>, <>, <>, <>, and <>. -[[LanguageElement]] -==== LanguageElement -A LanguageElement is an element with an identity within a <>. +[[LanguageEntity]] +==== LanguageEntity +A LanguageEntity is an entity with an identity directly contained in a <>. .Example -For example, _Invoice_, _Currency_, _Named_, or _String_ could be LanguageElements. +For example, _Invoice_, _Currency_, _Named_, or _String_ could be LanguageEntities. .EMF & MPS equivalent -LanguageElement is similar to Ecore’s `EClassifier`. +LanguageEntity is similar to Ecore’s `EClassifier`. -LanguageElement is similar to MPS’ `IStructureElement`. +LanguageEntity is similar to MPS’ `IStructureElement`. The difference is that `IStructureElement` includes also elements that cannot appear as top level elements of a structure aspects, such as `LinkDeclaration`, `PropertyDeclaration`, and `EnumerationMemberDeclaration`. .Characteristics -A LanguageElement has a <> and an <>. +A LanguageEntity has a <> and an <>. -A LanguageElement is a <> (as it has an identity, and it is contained in the namespace of its <>). +A LanguageEntity is a <> (as it has a key), and indirectly an <> (as it has a name). -A LanguageElement can be one of: +A LanguageEntity can be one of: * <> * <> * <> * <> -The `qualifiedName` of a LanguageElement can be obtained by combining the name of the containing <> with the name of the Concept. - .Constraints -Each LanguageElement must have a unique `name` within the Language. +Each LanguageEntity must have a unique `name` within the Language. -Each LanguageElement belongs to one and only one Language. +Each LanguageEntity belongs to one and only one Language. -[[FeaturesContainer]] -==== FeaturesContainer -Something which can own <>. +[[Classifier]] +==== Classifier +Something which can own <>.{fn-org105} .Example A Concept can have several features. .EMF & MPS equivalent -FeaturesContainer is similar to `EClass` in Ecore (which is used both for classes and interfaces) and to `AbstractConceptDeclaration` in MPS. +Classifier is similar to `EClass` in Ecore (which is used both for classes and interfaces) and to `AbstractConceptDeclaration` in MPS. .Characteristics -A FeaturesContainer has a <> and an <>. +A Classifier has a <> and an <>. + +It also represents the <> for <>. + -[[FeaturesContainer.features, FeaturesContainer.features]] -A FeaturesContainer owns any number of <> in `features` containment. +[[Classifier.features, Classifier.features]] +A Classifier owns any number of <> in `features` containment. -A FeaturesContainer can be one of: +A Classifier can be one of: * <> * <> -A FeaturesContainer is a <> (as it is a top level element in a <>) and a <> (as it act as the namespace for its features). -It is indirectly a <> (as it has an identity, and it is contained in the namespace of the Language). +A Classifier is a <> (as it is a top level element in a <>). +It is indirectly a <> (as it has a key) and an <> (as it has a name). .Constraints TBD [[DataType]] ==== DataType -A type of value which has not a relevant identity in the context of a model. +A type of value which has no relevant identity in the context of a model. .Example A _Currency_ or a _Date_ type. @@ -408,10 +386,10 @@ It is similar to Ecore’s `EDataType`. It is similar to MPS’ `DataTypeDeclaration`. .Characteristics -A DataType has a <> and an <>. +A DataType has a <> and an <>. -A DataType is a <> (as it is a top level element in a <>). -It is indirectly a <> (as it has an identity, and it is contained in the namespace of the Language). +A DataType is a <> (as it is a top level element in a <>). +It is indirectly a <> (as it has a key) and an <> (as it has a name). A DataType can be one of: @@ -438,12 +416,12 @@ They have no `default value`. Different from MPS' `Link`, Features CANNOT be specialized.{fn-org8} .Characteristics -A Feature has a <> and an <>. +A Feature has a <> and an <>. [[Feature.optional, Feature.optional]] A Feature can be set to `optional` or required. -A Feature is a <> (as it has an identity, and it is contained in the namespace of the <>). +A Feature is a <> (as it has a key) and indirectly an <> (as it has a name). A Feature can either be one of: @@ -452,9 +430,7 @@ A Feature can either be one of: * <> .Constraints -Each Feature MUST have a unique name within a specific <>. - -#TODO: Can we define features with the same name as an inherited one?# +Each Feature MUST have a unique name within a specific <>, including all (directly or indirectly) inherited Features.{fn-org139} We CAN have non-unique _inherited_ feature _names_, as in this example: @@ -488,7 +464,7 @@ If a host language cannot handle this situation, the generator towards that lang [[Link]] ==== Link -Represent a connection to an <>. +Represent a connection to an <>. .Example An _Invoice_ can be connected to its _InvoiceLines_ and to a _Customer_. @@ -499,17 +475,17 @@ It is similar to Ecore’s `EReference`. It is similar to MPS’ `LinkDeclaration`. .Characteristics -A Link has a <> and an <>. +A Link has a <> and an <>. It can be marked as <>. [[Link.multiple, Link.multiple]] A Link can have `multiple` or only a single targets. [[Link.type, Link.type]] -A Link refers its `type`, which is a <>. +A Link refers its `type`, which is a <>. -A Link is a <> (as it describes the characteristics of a <>). -It is indirectly a <> (as it has an identity, and it is contained in the namespace of its FeaturesContainer). +A Link is a <> (as it describes the characteristics of a <>). +It is indirectly a <> (as it has a key) and an <> (as it has a name). A Link can be either a <>, or a <>. @@ -520,64 +496,124 @@ TBD === Interfaces -The interfaces are <>. +The interfaces are <>. -[[NamespaceProvider]] -==== NamespaceProvider -Something which can act as the namespace for contained named things. +[[IKeyed]] +==== IKeyed +Something with a name that has a key.{fn-org142}{fn-org143} .Example -A Language `com.foo.Accounting` can be the NamespaceProvider for a Concept _Invoice_, which will therefore have the qualifiedName `com.foo.Accounting.Invoice`. +A Concept _Invoice_, contained in a Language `com.foo.Accounting`. .EMF & MPS equivalent n/a .Characteristics -[[NamespaceProvider.namespaceQualifier, NamespaceProvider.namespaceQualifier]] -A NamespaceProvider can calculate the `namespaceQualifier` exposed to its children. -This is typically calculated by combining the namespaces of all the ancestors up to the top level ancestor. +[[IKeyed.key, IKeyed.key]] +An IKeyed has a <> and an `key`.{fn-org90} + +A IKeyed is an <> (as it has a name). + +All elements of the Meta-Metamodel realize `IKeyed`. .Constraints -TBD +A IKeyed's `name` MUST be unique within the namespace (i.e. <>, <>, or <>). +The name MUST be a valid programming language identifier{fn-org48}. -=== Supporting Terminology -==== Multiplicity -Multiplicity describes how many targets a link must and can have. +More specifically, we allow https://docs.oracle.com/javase/specs/jls/se20/html/jls-3.html#jls-3.8[Java identifiers] with the following modifications: -.Example -Common multiplicities are `1` (meaning there MUST be exactly one target), `0..1` (meaning there CAN be exactly one target), `0..\*` (meaning there CAN be zero or more targets), and `1..*` (meaning there MUST be at least one target, but there CAN be more than one targets). +* We do NOT allow `$` (dollar sign) +* _ReservedKeyword_, _BooleanLiteral_, and _NullLiteral_ (as per Java identifier spec) are allowed identifiers. -.EMF & MPS equivalent -In Ecore there is no equivalent as `lowerBound` and `upperBound` can be set independently. +Effectively: -This is equivalent to MPS’ `Cardinality`, which has the four values mentioned as example. +* Names MUST NOT start with a number. +* Names MUST NOT be empty. +* Names MUST NOT contain spaces. +* Names CAN use Unicode characters, numbers, and underscore. -.Characteristics -LionCore represents multiplicity as the two booleans <> (whether there MUST be at least one target) and <> (whether there CAN be more than one target). +NOTE: These restrictions only apply to names of Language elements (i.e. M3 concepts/M2 instances). +Any language that uses `INamed` on its own can establish their own constraints. -[%autowidth] +Refer to <> for more constraints. + +=== Pre-defined Ids and Keys +The language itself has key `LIonCore-M3`.{fn-org91} + +==== Keys of M3 Elements + +[cols="d,d,m"] |=== -|Multiplicity |`optional` |`multiple` -|`1` |true |false -|`0..1` |false |false -|`0..*` |true |true -|`1..*` |false |true +|M3 element |Concept |Key + +|<> |Concept |Concept +|<> |Property |Concept-abstract +|<> |Reference |Concept-extends +|<> |Reference |Concept-implements +|<> |Concept |ConceptInterface +|<> |Reference |ConceptInterface-extends +|<> |Concept |Containment +|<> |Concept |DataType +|<> |Concept |Enumeration +|<> |Containment |Enumeration-literals +|<> |Concept |EnumerationLiteral +|<> |Concept |Feature +|<> |Property |Feature-optional +|<> |Concept |Classifier +|<> |Containment |Classifier-features +|<> |Concept |Link +|<> |Property |Link-multiple +|<> |Reference |Link-type +|<> |Concept |Language +|<> |Reference |Language-dependsOn +|<> |Containment |Language-entities +|<> |Property |Language-version +|<> |Concept |LanguageEntity +|<> |ConceptInterface |IKeyed +|<> |Property |IKeyed-key +|<> |Concept |PrimitiveType +|<> |Concept |Property +|<> |Reference |Property-type +|<> |Concept |Reference |=== -.Constraints -TBD +==== Ids of Built-in elements +The language hosting built-in elements has key `LIonCore-builtins`.{fn-org141} + +Every language implicitly depends on this language.{fn-org9-implicit} +Thus, the ids in this language MUST be stable. +This means the id MUST be identical to the key for each node in this language. + +[cols="d,d,m"] +|=== +|Instance |Concept |Id and key + +|<> |PrimitiveType |LIonCore-builtins-String +|<> |PrimitiveType |LIonCore-builtins-Boolean +|<> |PrimitiveType |LIonCore-builtins-Integer +|<> |PrimitiveType |LIonCore-builtins-JSON +|<> |Concept |LIonCore-builtins-Node +|<> |ConceptInterface |LIonCore-builtins-INamed +|<> |Property |LIonCore-builtins-INamed-name +|=== -== Other considerations [[stdlib, standard library]] -=== Pre-defined elements -Each LIonWeb implementation ships with a set of pre-defined elements, akin to a _standard library_. +=== Built-in elements +Each LIonWeb implementation ships with a set of built-in elements, akin to a _standard library_. ==== Concepts [[Node, Node]] * `Node`{fn-org71}, an _abstract_ <> that's the (explicit or implicit) the ancestor of all concepts. +==== Interfaces + +[[INamed, INamed]] +* `INamed`{fn-org86}, an <> with one <> called [[INamed.name]]`name` of type <>. ++ +If a <> targets a Classifier that implements INamed, implementations SHOULD use the target's `name` property as default <<{serialization}.adoc#Reference.reference.resolveInfo, resolveInfo>> value. + ==== Primitive types Some <> will be widely used, so it makes sense to pre-define them.{fn-org9} @@ -587,29 +623,49 @@ Some <> will be widely used, so it makes sense t * [[Integer, Integer]] `Integer` * [[JSON, JSON]] `JSON` -=== Annotations -We intend to support annotations in a future release.{fn-org13} +=== Supporting Terminology +==== Multiplicity +Multiplicity describes how many targets a link must and can have. -=== Reflection +.Example +Common multiplicities are `1` (meaning there MUST be exactly one target), `0..1` (meaning there CAN be exactly one target), `0..\*` (meaning there CAN be zero or more targets), and `1..*` (meaning there MUST be at least one target, but there CAN be more than one targets). -Reflection describes the ability of each Meta-Metamodel instance to access the definition of the Meta-Metamodel element from which it has been instantiated. +.EMF & MPS equivalent +In Ecore there is no equivalent as `lowerBound` and `upperBound` can be set independently. -It is important to offer this functionality also in consideration that some implementation languages may not offer reflection capabilities that could be used as an alternative. +This is equivalent to MPS’ `Cardinality`, which has the four values mentioned as example. -=== Generics +.Characteristics +LionCore represents multiplicity as the two booleans <> (whether there MUST be at least one target) and <> (whether there CAN be more than one target). -Generics are not directly supported by this proposal. -We can solve some needs through specialization of features in derived classes. -We could alternatively also imagine using specific annotations for supporting this. +[%autowidth] +|=== +|Multiplicity |`optional` |`multiple` +|`1` |true |false +|`0..1` |false |false +|`0..*` |true |true +|`1..*` |false |true +|=== -In general Generics complicate the solution and MPS can live without them. -Also, in StarLasu we never encountered the need for them so far. +.Constraints +TBD + +[[partition]] +==== Partitions +Each node that does not have a parent node MUST be of a Concept with <> flag set to `true`. +This implies that every node is contained in exactly one partition, namely the partition defined by its root node.{fn-org29} +Partitions CANNOT be nested. + +.EMF & MPS equivalent +A partition is similar to ECore's `Resource`. + +A partition is similar to MPS' `model`. [[identifiers]] -=== Identifiers +==== Identifiers -==== Valid characters +===== Valid characters Ids can only contain these symbols: @@ -621,18 +677,18 @@ Ids can only contain these symbols: This is the same character set as https://en.wikipedia.org/wiki/Base64#Variants_summary_table[Base64url variant]. -==== Representation +===== Representation Ids are represented by a string, containing only valid characters (as defined above). An id string is NOT padded, also not by whitespaces. An id string does NOT contain any terminating symbols (compared to some BASE64 variants); this does not affect internal representation in a specific implementation language, e.g. C-style \0-terminated strings. -==== Scope +===== Scope Node ids MUST be unique within their id-space. [[id-space]] -===== Id-space +====== Id-space An id-space is a realm that guarantees the uniqueness of all ids within. Typically, this means one repository. @@ -644,11 +700,54 @@ In LIonWeb (the protocol), id-spaces are NOT hierarchical. An implementation might choose to use hierarchical id-spaces internally. [[node-id]] -==== Identification +===== Identification A node can be identified relative to its id-space by the node's id. To globally identify a node, we use the combination of the id-space id and the node id. +[[keys]] +==== Keys +We use keys when we refer from _instance level_ to _meta level_.{fn-org80} +Refer to <> for a list of all usages. + +Keys are modeled via <>. +Keys MUST be valid <>. + +A key SHOULD be globally unique, and MUST be unique within an <>, i.e. the Language.{fn-org91} +For approximate global uniqueness, we SHOULD adopt Java's package naming scheme, based on domain names. +As we don't allow dots (`.`) in ids, we SHOULD use dashes (`-`) instead. + +[[namespaces]] +==== Namespaces +A Namespace implements <> and can have descendants that implement <>. + +Typically, a namespace enforces some constraints on the contained names, like uniqueness within the same namespace, or what's considered a valid name. + +We can calculate a fully qualified name by concatenating the namespaces of all the ancestors up to the top level ancestor. +Future versions might support this directly.{fn-org146} + +== Other considerations + +=== Annotations + +We intend to support annotations in a future release.{fn-org13} + +=== Reflection + +Reflection describes the ability of each Meta-Metamodel instance to access the definition of the Meta-Metamodel element from which it has been instantiated. + +It is important to offer this functionality also in consideration that some implementation languages may not offer reflection capabilities that could be used as an alternative. + +=== Generics + +Generics are not directly supported by this proposal. +We can solve some needs through specialization of features in derived classes. +We could alternatively also imagine using specific annotations for supporting this. + +In general Generics complicate the solution and MPS can live without them. +Also, in StarLasu we never encountered the need for them so far. + +[[references-to-language-elements]] === References to Language Elements From a language, we refer to all language elements by their <>.{fn-org131} This includes references to @@ -658,7 +757,9 @@ This includes references to * <> or <> Interfaces * Types of <> or <> -From an instance, we refer to its defining language element by the language element's <>. +As the <> is just another language, we refer to its members by their id, just as any other language members. + +From an instance, we refer to its defining language element by the language element's <>{fn-org80} This includes references to * <> usage @@ -668,70 +769,34 @@ This includes references to * <> assignment * <> value -#TODO: How to refer to stdlib elements? By id or key?# - -=== Pre-defined Ids and Keys -==== Keys of M3 Elements -[cols="d,d,m"] -|=== -|M3 element |Concept |Key +=== Union or Intersection Types -|<> |Concept |LIonCore_M3_Concept -|<> |Property |LIonCore_M3_Concept_abstract -|<> |Reference |LIonCore_M3_Concept_extends -|<> |Reference |LIonCore_M3_Concept_implements -|<> |Concept |LIonCore_M3_ConceptInterface -|<> |Reference |LIonCore_M3_ConceptInterface_extends -|<> |Concept |LIonCore_M3_Containment -|<> |Concept |LIonCore_M3_DataType -|<> |Concept |LIonCore_M3_Enumeration -|<> |Containment |LIonCore_M3_Enumeration_literals -|<> |Concept |LIonCore_M3_EnumerationLiteral -|<> |Concept |LIonCore_M3_Feature -|<> |Property |LIonCore_M3_Feature_optional -|<> |Concept |LIonCore_M3_FeaturesContainer -|<> |Containment |LIonCore_M3_FeaturesContainer_features -|<> |Concept |LIonCore_M3_Link -|<> |Property |LIonCore_M3_Link_multiple -|<> |Reference |LIonCore_M3_Link_type -|<> |Concept |LIonCore_M3_Language -|<> |Property |LIonCore_M3_Language_name -|<> |Property |LIonCore_M3_Language_key -|<> |Reference |LIonCore_M3_Language_dependsOn -|<> |Containment |LIonCore_M3_Language_elements -|<> |Concept |LIonCore_M3_LanguageElement -|<> |Concept |LIonCore_M3_NamespacedEntity -|<> |Property |LIonCore_M3_NamespacedEntity_name -|<> |Property |LIonCore_M3_NamespacedEntity_key -|<> |Concept |LIonCore_M3_NamespaceProvider -|<> |Concept |LIonCore_M3_PrimitiveType -|<> |Concept |LIonCore_M3_Property -|<> |Reference |LIonCore_M3_Property_type -|<> |Concept |LIonCore_M3_Reference -|=== +These are not supported. -==== Ids of Built-in Instances +=== Operations -[cols="d,d,m"] -|=== -|Instance |Concept |Id +Operations are not represented in the Meta-Metamodel. -|<> |PrimitiveType |LIonCore_M3_String -|<> |PrimitiveType |LIonCore_M3_Boolean -|<> |PrimitiveType |LIonCore_M3_Integer -|<> |PrimitiveType |LIonCore_M3_JSON -|<> |Concept |LIonCore_M3_Node -|=== +== Reference models +=== Meta-meta model +The LIonCore model, aka LIonWeb M3. +It is link:lioncore.json[defined] by means of itself, as outlined by link:https://en.wikipedia.org/wiki/Meta-Object_Facility[Meta-Object Facility]. -=== Union or Intersection Types +[source, json] +---- +include::lioncore.json[] +---- -These are not supported. +=== Pre-defined elements +The LIonCore link:builtins.json[built-in] elements. -=== Operations +[source, json] +---- +include::builtins.json[] +---- -Operations are not represented in the Meta-Metamodel. == Comparison with other meta-metamodels @@ -794,16 +859,16 @@ link:https://alexanderpann.github.io/mps-openapi-doc/javadoc_2021.2/org/jetbrain (link:https://www.jetbrains.com/help/mps/structure.html#properties[docs], link:https://alexanderpann.github.io/mps-openapi-doc/javadoc_2021.2/org/jetbrains/mps/openapi/language/SProperty.html[javadoc]) -|<> +|<> |-- |-- -|<> +|<> |link:https://download.eclipse.org/modeling/emf/emf/javadoc/2.11/org/eclipse/emf/ecore/EClassifier.html[EClassifier] |link:http://127.0.0.1:63320/node?ref=r%3A00000000-0000-4000-0000-011c89590292%28jetbrains.mps.lang.structure.structure%29%2F1588368162880706270[IStructureElement] (link:https://alexanderpann.github.io/mps-openapi-doc/javadoc_2021.2/org/jetbrains/mps/openapi/language/SElement.html[javadoc]) -|<> +|<> |link:https://download.eclipse.org/modeling/emf/emf/javadoc/2.11/org/eclipse/emf/ecore/EClass.html[EClass] |link:http://127.0.0.1:63320/node?ref=r%3A00000000-0000-4000-0000-011c89590292%28jetbrains.mps.lang.structure.structure%29%2F1169125787135[AbstractConceptDeclaration] (link:https://alexanderpann.github.io/mps-openapi-doc/javadoc_2021.2/org/jetbrains/mps/openapi/language/SAbstractConcept.html[javadoc]) @@ -824,10 +889,6 @@ link:https://alexanderpann.github.io/mps-openapi-doc/javadoc_2021.2/org/jetbrain |link:http://127.0.0.1:63320/node?ref=r%3A00000000-0000-4000-0000-011c89590292%28jetbrains.mps.lang.structure.structure%29%2F1071489288298[LinkDeclaration] (https://alexanderpann.github.io/mps-openapi-doc/javadoc_2021.2/org/jetbrains/mps/openapi/language/SAbstractLink.html[javadoc]) -|<> -|-- -|-- - |=== diff --git a/lioncore/metametamodel/metametamodel.puml b/lioncore/metametamodel/metametamodel.puml new file mode 100644 index 0000000..b6c3c62 --- /dev/null +++ b/lioncore/metametamodel/metametamodel.puml @@ -0,0 +1,74 @@ +@startuml +hide empty members + +package builtins { + interface builtins.INamed { + name: String + } +} + +class Concept #LightGreen extends Classifier { + abstract: Boolean + partition: Boolean +} + +class ConceptInterface #LightGreen extends Classifier + +class Containment #LightBlue extends Link + +abstract class DataType #LightPink extends LanguageEntity + +class Enumeration #LightPink extends DataType + +class EnumerationLiteral #LightPink implements IKeyed + +abstract class Feature #LightBlue implements IKeyed { + optional: Boolean +} + +abstract class Classifier #LightGreen extends LanguageEntity + +abstract class Link #LightBlue extends Feature { + multiple: Boolean +} + +class Language <> implements IKeyed { + version: Integer +} + +abstract class LanguageEntity implements IKeyed + +interface IKeyed extends builtins.INamed { + key: Id +} + +class PrimitiveType #LightPink extends DataType + +class Property #LightBlue extends Feature + +class Reference #LightBlue extends Link + +' relations: + +Concept "*" -> "0..1" Concept: extends +Concept "*" --> "*" ConceptInterface: implements + +ConceptInterface "*" --> "*" ConceptInterface: extends + +EnumerationLiteral "*" -* "1" Enumeration : literals + +Feature "*" -* "1" Classifier: features + +Link "*" --> "1" Classifier: type + +Language "*" --> "*" Language: dependsOn +LanguageEntity "*" -* "1" Language: entities + +Property "*" -> "1" DataType: type + +legend + <#LightGray,#LightGray>| <#LightBlue>Feature | + | <#LightGreen>Classifier | + | <#LightPink>DataType | +end legend +@enduml diff --git a/lioncore/metametamodel_simplified.puml b/lioncore/metametamodel/metametamodel_simplified.puml similarity index 100% rename from lioncore/metametamodel_simplified.puml rename to lioncore/metametamodel/metametamodel_simplified.puml diff --git a/lioncore/serialization.adoc b/lioncore/serialization.adoc deleted file mode 100644 index a3bc0b1..0000000 --- a/lioncore/serialization.adoc +++ /dev/null @@ -1,830 +0,0 @@ -include::issue-footnotes.adoc[] - -:fn-mof: footnote:mof[https://en.wikipedia.org/wiki/Meta-Object_Facility[Meta-Object Facility], also known as M3 model] - -= LIonWeb Serialization Format - -== Conventions used in this document -* _italic_ words refer to concepts defined by JSON. -* *bold* words refer to concepts defined in this document. -* `monospaced` words describe verbatim contents of the serialization. -* Footnotes refer to more discussions and rationale, but are non-normative. - -== Design Goals -We do not take any measures to reduce the amount of transmitted data.{fn-org73} - - -== Description -LIonWeb node serialization format is defined in JSON (https://datatracker.ietf.org/doc/html/rfc8259[RFC 8259]). - -=== Root structure - -Root level MUST be an _object_ with three members. - -##TODO: Are more members allowed?{fn-org67}## - -The first member MUST be _key_ `serializationFormatVersion` with a _string_ _value_.{fn-org58} -The value MUST be a decimal integer (without leading or trailing whitespace) describing the serialization format version used to create the processed document, according to <>. - -The second member MUST be _key_ `languages` with an _array_ _value_.{fn-org76}{fn-org78} -Each _element_ in the value array MUST adhere to <>. -The order of _elements_ is undefined. -_elements_ MUST contain all language/version referred to by any <> in the processed document. -Each _element_ must be unique with respect to all its _members_. - -The third member MUST be _key_ `nodes` with an _array_ _value_.{fn-org33} -Each _element_ in the value array MUST adhere to <>. -The order of _elements_ is undefined. -Each _element_ must be unique with respect to the value of its _key_ `id`. - -[[language]] -=== Language structure -Each *used language* MUST be an _object_. -The order of _members_ is undefined. - -The _object_ MUST contain the following _members_:{fn-org76} - -* _key_ `key` with _string_ _value_, adhering to <>. -* _key_ `version` with _string_ _value_, adhering to <>. - -[[language-key]] -==== Language key -A _string_ according to <>. -Refers to the <> of the language. - -[[language-version]] -==== Language version -A _string_ with any contents{fn-org128}{fn-org130}, MUST NOT be empty.{fn-org92} -Refers to the <> of the language. - -[[meta-pointer]] -=== Meta-pointer -A *meta-pointer* is a reference from M1 to M2.{fn-org89}{fn-mof} -It's used at several places within <>. - -Each meta-pointer MUST be an _object_. -The order of _members_ is undefined. - -The _object_ MUST contain the following members: - -* _key_ `language` with _string_ _value_, adhering to <>. -* _key_ `version` with _string_ _value_, adhering to <>. -* _key_ `key` with _string_ _value_ according to <>. -Refers to some <>. -Which element exactly is specified for each usage of meta-pointer. - -[[node]] -=== Node structure -Each *node* MUST be an _object_.{fn-org37} -The order of _members_ is undefined. - -The _object_ MUST contain the following _members_:{fn-org59}{fn-java33}{fn-org55} - -* _key_ `id` with _string_ _value_, adhering to <>. -* _key_ `concept`{fn-org37-name} with _object_ _value_, adhering to <>. - The *meta-pointer*'s ``key``'s _value_ refers to the <> of the <> this *node* is an instance of. -* _key_ `properties` with _array_ _value_, each _element_ adhering to <>. -The order of _elements_ is undefined. -* _key_ `children`{fn-org55-name-children} with _array_ _value_, each _element_ adhering to <>. -The order of _elements_ is undefined. -* _key_ `references`{fn-org55-name-references} with _array_ _value_, each _element_ adhering to <>. -The order of _elements_ is undefined. -* _key_ `parent` with _string_ or _null_ _value_, adhering to <>. - -##TODO: How to store invalid text?{fn-org62}## - - -[[id]] -==== Id value -A _string_ according to <>. -Defines the *id* of this *node*. - - -[[property]] -==== Property -Each *property* MUST be an _object_. -The order of _members_ is undefined. - -The _object_ MUST contain the following _members_: - -* _key_ `property` with _object_ _value_, adhering to <>. - The *meta-pointer*'s ``key``'s _value_ refers to the <> of the <> this *property* is an instance of. -* _key_ `value` with _value_ as one of -** _string_{fn-org34} containing the value of the property referenced by the `property`. -Refer to <> for the specification of the value format. -CAN be an empty _string_. -** _null_ to explicitly specify the property to be unset. - - -[[child]] -==== Child -Each *child* MUST be an _object_. -The order of _members_ is undefined. - -The _object_ MUST contain the following _members_: - -* _key_ `containment` with _object_ _value_, adhering to <>. -The *meta-pointer*'s ``key``'s _value_ refers to the <> of the <> this *child* is an instance of. -* _key_ `children` with _array_ _value_ with _string_ _elements_. -Each _element_ adheres to <>, and refers to the *id* of the contained *node*. -The order of _elements_ is undefined. -+ -NOTE: Each *child* element is the inverse relation of *parent*. -+ -NOTE: The children *node* CAN be contained in the processed document, but also CAN be outside the processed document (i.e. not contained in the processed document). - -[[reference]] -==== Reference -Each *reference* MUST be an _object_. -The order of _members_ is undefined. - -The _object_ MUST contain the following _members_: - -* _key_ `reference` with _object_ _value_, adhering to <>. -The *meta-pointer*'s ``key``'s _value_ refers to the <> of the <> this *reference* is an instance of. -* _key_ `targets` with __object_ _elements_. -Each _element_ MUST have the following _members_ in undefined order:{fn-org55-name-references} -** _key_ `resolveInfo`{fn-org36} with _value_ as one of: -*** _string_ containing *resolveInfo*, a textual hint that might be used to find the target *node* of this reference. -The exact value depends on the implementation. -CAN be an empty _string_. -*** _null_ if no *resolveInfo* is available. - -** _key_ `reference`{fn-org35} with _value_ as one of: -*** _string_ according to <>. -Refers to the *id* of the target *node*. -+ -NOTE: The referred *node* CAN be contained in the processed document, but also CAN be outside the processed document (i.e. not contained in the processed document). -*** _null_ if the *id* of the target *node* is not known. - -[[parent]] -==== Parent -One of - -* _string_ according to <>. -Refers to the *id* of the *node* containing this *node*. -+ -NOTE: *parent* is the inverse relation of one *child*. -+ -NOTE: The referred *node* CAN be contained in the processed document, but also CAN be outside the processed document (i.e. not contained in the processed document). - -* _null_ if -** This *node* is a *root node*, i.e. this node does not have a parent. -** This serialization is sent as an update request. - -[[property-values]] -=== Property serialization -All property values MUST be serialized as JSON _string_.{fn-org34}{fn-org9}. -An unset property CAN be serialized as JSON _null_. - -==== String -<> might be any string, of any length, including (but not limited to): - -* empty string: `""` -* only containing whitespace: `" "` -* containing escaped characters as per JSON spec: `"They said:\n \"Hello!\""` -* containing extended Unicode characters: `"😐"` -* containing escaped Unicode characters: `"\uD83D\uDE10"` - -==== Boolean -<> MUST be encoded as one of these JSON _strings_: - -* `"true"` -* `"false"` - -Booleans MUST NOT be encoded with leading or trailing whitespace, uppercase characters, short forms (like `t` or `f`), or decimal representation (like `1`, `0`, `-1`). - -==== Integer -<> MUST be encoded as JSON _string_. - -* Integers MUST be represented in base-10. -* The digits CAN be prefixed with either `+` (plus) or `-` (minus).{fn-org100} -* Integers MUST NOT be prefixed by leading zeros. -* Integers CAN contain value zero with any prefix, i.e. `0`, `-0`, or `+0`. -* Integers MUST NOT contain leading or trailing whitespace. -* LIonWeb does NOT limit the range of the integer value. - An implementation MAY refuse a model containing an integer value outside the supported range. - Every implementation MUST support at least 32 bit signed integer range. - ##TODO supported integer range?##{fn-org9-intrange} - -.Examples of valid Integer encodings - -* `"0"` -* `"+0"` -* `"-0"` -* `"123"` -* `"-100000"` -* `"+999"` -* `"100000000200000000300000000400000000500000000600000000700000000800000000900000000999999999"` -* `"-999999999900000000800000000700000000600000000500000000400000000300000000200000000100000000"` - -.Examples of invalid Integer encodings - -* `""` -* `123` -* `-1` -* `"+-0"` -* `"++1"` -* `"00002"` -* `"0xAA12"` -* `" 5"` -* `"-6 "` - -==== JSON -<> MUST be encoded as JSON _string_. -All double quotes, line breaks, etc. MUST be escaped to form a proper JSON _string_. -The value MUST adhere to JSON spec (RFC 8259). - -.Valid example -`"{ \"key\": \"my value\",\n\"myArray\": [1, -2, true] }"` - -.Invalid example -`{ "key": "my value", "myArray": [1, -2, true] }` - -==== Enumeration Literals -<> MUST be encoded as JSON _string_ _value_ according to <>. -MUST refer to the <> of an <> of the <> defined as <> of this *Property*.{fn-org128} - -== Examples - -=== Minimal -[source,json] ----- -{ - "serializationFormatVersion": "1", - "languages": [], - "nodes": [] -} ----- - -=== Minimal node -[source,json] ----- -{ - "serializationFormatVersion": "1", - "languages": [ - { - "key": "myLanguage", - "version": "2" - } - ], - "nodes": [ - { - "id": "aaa", - "concept": { - "language": "myLanguage", - "version": "2", - "key": "myConceptId" - }, - "properties": {}, - "children": {}, - "references": {}, - "parent": null - } - ] -} ----- - -=== Property variants - -For this example, we need to define an enumeration and a concept that uses the enumeration. - -NOTE: The format used in this example is non-normative. - -Assume this enumeration: -[source] ----- -enumeration DaysOfWeek [id 23, key days-of-week] - - literal Monday [id 34, key monday] - literal Tuesday [id 2, key tttt] - literal Wednesday [id 55, key 12398712] ----- - -And this concept: -[source] ----- -concept OpeningTime [id 44, key time_to_open] - property day: DaysOfWeek [id 42, key day] - property startHour: Integer [id 22, key starthour] - property endHour: Integer [id 89, key endhour] ----- - -[source,json] ----- -{ - "serializationFormatVersion": "1", - "languages": [ - { - "key": "myLanguage", - "version": "2" - } - ], - "nodes": [ - { - "id": "bbb", - "concept": { - "language": "myLanguage", - "version": "2", - "key": "myConceptId" - }, - "properties": [ - { - "property": { - "language": "myLanguage", - "version": "2", - "key": "stringPropertyId" - }, - "value": "my string value" - }, - { - "property": { - "language": "myLanguage", - "version": "2", - "key": "integerPropertyId" - }, - "value": "123" - }, - { - "property": { - "language": "myLanguage", - "version": "2", - "key": "booleanPropertyId" - }, - "value": "true" - }, - { - "property": { - "language": "myLanguage", - "version": "2", - "key": "jsonPropertyId" - }, - "value": "{ \"name\": \"Bob\" }" - }, - { - "property": { - "language": "myLanguage", - "version": "2", - "key": "unsetPropertyId" - }, - "value": null - } - ], - "children": {}, - "references": {}, - "parent": null - }, - { - "id": "21", - "concept": { - "language": "myLanguage", - "version": "2", - "key": "time_to_open" - }, - "properties": [ - { - "property": { - "language": "myLanguage", - "version": "2", - "key": "day" - }, - "value": "tttt" - }, - { - "property": { - "language": "myLanguage", - "version": "2", - "key": "starthour" - }, - "value": "9" - }, - { - "property": { - "language": "myLanguage", - "version": "2", - "key": "endhour" - }, - "value": "5" - } - ], - "children": [], - "references": [], - "parent": null - } - ] -} ----- - -=== Children variants -[source,json] ----- -{ - "serializationFormatVersion": "1", - "languages": [ - { - "key": "myLanguage", - "version": "2" - } - ], - "nodes": [ - { - "id": "ccc", - "concept": { - "language": "myLanguage", - "version": "2", - "key": "myConceptId" - }, - "properties": {}, - "children": [ - { - "containment": { - "language": "myLanguage", - "version": "2", - "key": "emptyContainmentId" - }, - "children": [] - }, - { - "containment": { - "language": "myLanguage", - "version": "2", - "key": "singleContainmentId" - }, - "children": [ - "cdd" - ] - }, - { - "containment": { - "language": "myLanguage", - "version": "2", - "key": "multiContainmentId" - }, - "children": [ - "cee", - "cff", - "cgg" - ] - } - ], - "references": {}, - "parent": null - }, - { - "id": "cgg", - "concept": { - "language": "myLanguage", - "version": "2", - "key": "differentConceptId" - }, - "properties": {}, - "children": {}, - "references": {}, - "parent": null - }, - { - "id": "cdd", - "concept": { - "language": "myLanguage", - "version": "2", - "key": "otherConceptId" - }, - "properties": {}, - "children": {}, - "references": {} - }, - { - "id": "cee", - "concept": { - "language": "myLanguage", - "version": "2", - "key": "differentConceptId" - }, - "properties": {}, - "children": {}, - "references": {}, - "parent": null - } - ] -} ----- - -*node* with *id* `cff` is outside the processed document. - -=== Reference variants -We support different kinds of targets.{fn-org57} -[source,json] ----- -{ - "serializationFormatVersion": "1", - "languages": [ - { - "key": "myLanguage", - "version": "2" - } - ], - "nodes": [ - { - "id": "ddd", - "concept": { - "language": "myLanguage", - "version": "2", - "key": "myConceptId" - }, - "properties": {}, - "children": {}, - "references": [ - { - "reference": { - "language": "myLanguage", - "version": "2", - "key": "emptyReferenceId" - }, - "targets": [] - }, - { - "reference": { - "language": "myLanguage", - "version": "2", - "key": "singleReferenceId" - }, - "targets": [ - { - "resolveInfo": "some name", - "reference": "dee" - } - ] - }, - { - "reference": { - "language": "myLanguage", - "version": "2", - "key": "multiReferenceId" - }, - "targets": [ - { - "resolveInfo": "self-reference", - "reference": "ddd" - }, - { - "resolveInfo": "only resolve info", - "reference": null - } - ] - }, - { - "reference": { - "language": "myLanguage", - "version": "2", - "key": "noResolveInfoReferenceId" - }, - "targets": [ - { - "resolveInfo": null, - "reference": "dee" - } - ] - }, - { - "reference": { - "language": "myLanguage", - "version": "2", - "key": "neitherResolveInfoNorReferenceId" - }, - "targets": [ - { - "resolveInfo": null, - "reference": null - } - ] - } - ], - "parent": null - }, - { - "id": "dee", - "concept": { - "language": "myLanguage", - "version": "2", - "key": "differentConceptId" - }, - "properties": {}, - "children": {}, - "references": {}, - "parent": null - } - ] -} ----- - - -[[versions]] -== Versions -=== 1 -Initial version. - - -[[possible-values]] -== Possible values for `properties`, `children`, and `references` -Only bold entries are valid.{fn-java33} - -[%header,cols="1a,1,1,1"] -|=== -|1 A + -Contents -|B + -``properties: {``_ _ _``}`` -|C + -``children: {``_ _ _``}`` -|D + -``references: {``_ _ _``}`` - -|2 `"a": "b"` -|*property with id `a` has value `b`* -.4+.^|`children` value must be array -.4+.^|`references` value must be array - -|3 `"c": ""` -|*property with id `c` has value (empty string)* -// |`children` value must be array -// |`references` value must be array - -|4 `"d": " "` -|*property with id `d` has value ` `(one space)* -// |`children`value must be array -// |`references`value must be array - -|5 `"e": null` -|*property with id `e` has no value* -// |`children` value must be array -// |`references` value must be array - -|6 (key `f` not present) -|*property with id `f` has no value* -|*containment with id `f` does not contain any nodes* -|*reference with id `f` does not point to any nodes* - -|7 `"g": []` -.9+.^|`properties` value must be string -|*containment with id `g` does not contain any nodes* -|*reference with id `g` does not point to any nodes* - -|8 `"h": [ "i" ]` -// |`properties`value must be string -|*containment with id `h` contains node with id`i`* -|`references` value array element must be object - -|9 - -[source%nowrap] ----- -"j": [ - { - "resolveInfo": "k", - "reference": "l" - } -] ----- -// |`properties` value must be string -.2+.^|`children` value array element must be string -|*reference with id `j` points to node with id `l`, re-binding supported by text `k`* - -|10 `"m": [ null ]` -// |`properties` value must be string -// |`children` value array element must be a string -|`references` value array element must be an object - -|11 `"n": true` -// |`properties` value must be string -.5+.^|`children` value must be array -.5+.^|`references` value must be array - -|12 `"o": 12` -// |`properties` value must be string -// |`children` value must be array -// |`references` value must be array - -|13 `"p": 34.56` -// |`properties` value must be string -// |`children` value must be array -// |`references` value must be array - -|14 `"q": {}` -// |`properties` value must be string -// |`children` value must be array -// |`references` value must be array - -|15 `"r": {`...`}` -// |`properties` value must be string -// |`children` value must be array -// |`references` value must be array - -|16 `"s": foo` -3.2+^.^|JSON syntax error -// |JSON syntax error -// |JSON syntax error - -|17 `"t": undefined` -// |JSON syntax error -// |JSON syntax error -// |JSON syntax error -|=== - -[[ref-resolve-null]] -== Meaning and rationale of `null` values for reference id and resolveInfo - -Based on{fn-org36-null} - -NOTE: We only consider low-level model structure here. -If we had a reference of type `Car`, but the id points to an existing `Wheel`, we would _still_ consider the reference valid on this low level. - -In the following matrix, the columns describe _reference_, the rows _resolveInfo_. - -reference: - -* _valid_ means there it is known that a node with the target id exists. -Undefined whether the targeted node is part of the same model fragment, known locally, or only known to the repository. -* _unknown_ means we don't know whether a node with the target id exists. -* _invalid_ means we know that no node with the target id exists. - -resolveInfo: - -* _uniquely resolvable_ means that the resolver[1] can find exactly one existing node that could match the given resolve info. -* _ambiguously resolvable_ means that the resolver[1] can find more than one existing node that could match the given resolve info. -* _non-resolvable_ means that the resolver[1] can not find any existing node that could match the given resolve info. - -ad [1]: It's currently undefined who the resolver is. -We just assume it can somehow interpret the resolve info, and can return [0..*] valid target nodes. - -[%header,cols=">h,<,<,<,<"] -|=== -|id → + -resolveInfo ↓ -^|non-null, valid -^|non-null, unknown -^|non-null, invalid -^|null - -|non-null, uniquely resolvable -|happy case -|transient, resolvable -|brittle -|brittle - -|non-null, ambiguously resolvable -|mostly happy -|transient -|external selection required -|external selection required - -|non-null, non-resolvable -|mostly happy -|transient -|external help required -|external help required - -|null -|mostly happy -|transient -|broken -|broken -|=== - -.Happy case -We know and can reach the target node of the reference. -We also have information how to find the target in case the target is not reachable (e.g. because it has been deleted). - -.Transient -We know a target node id, but don't know yet whether that node exists. - -.Resolvable -Either through node id or resolveInfo, we're sure we can eventually find our target. - -.Brittle -We cannot find the target node by id, but via resolveInfo. -However, resolveInfo might stop working at some point (e.g. if the target gets renamed before resolving the nodeInfo). - -.Mostly happy -We know and can reach the target node of the reference. -But we could not re-establish the reference if the target is not reachable (e.g. because the user cuts+pastes the target node, and the pasted one gets a new id). - -.External selection required -We don't know the target node. -However, we can present the user with a list of options to chose from. -We populate this list with the potential targets of the resolveInfo. - -.External help required -We don't know the target node, and cannot make sense of resolveInfo. -The user might use the resolveInfo to find the actual target. - -.Broken -We have no technical way to find the target node, or meaningful ways to support the user to find it. - -[NOTE] -==== -Instead of the user helping out, we might also infer the same information from language specifics. - -Example: Assume a function with only one parameter. -If we had a reference that can only target a parameter, we can infer that target to be the one parameter. -In practice, that means scoping could help us out here (but that's out of scope as of the first remark above). -==== \ No newline at end of file diff --git a/lioncore/serialization.puml b/lioncore/serialization.puml deleted file mode 100644 index a7bf2b7..0000000 --- a/lioncore/serialization.puml +++ /dev/null @@ -1,72 +0,0 @@ -@startuml -title Serialization Format - -hide empty members - -legend - <#transparent,#transparent>|= Legend |= | - | [key] / [value] | representation as JSON object | -end legend - -class SerializationChunk { - serializationFormatVersion: String -} - -SerializationChunk *--> "0..*" UsedLanguage: languages - -class UsedLanguage { - key: Id - version: String -} - -SerializationChunk *--> "0..*" Node: nodes - -class Node { - id: Id - parent: Id -} - -Node *--> "1" MetaPointer: concept - -class MetaPointer { - language: Id - version: String - key: Id -} - -Node *--> "0..*" Children: children - -class Children { -} - -Children *--> "1" MetaPointer: containment - -Children *--> "0..1" ChildTarget: children - -class ChildTarget { - target: Id -} - -Node *--> "0..*" References: references - -class References { -} - -References *--> "1" MetaPointer: reference - -References *--> "0..*" ReferenceTarget: targets - -class ReferenceTarget { - reference: Id - resolveInfo: String -} - -Node *--> "0..*" PropertyValue: properties - -class PropertyValue { - value: String -} - -PropertyValue *--> "1" MetaPointer: property - -@enduml \ No newline at end of file diff --git a/lioncore/serialization/children-variants.json b/lioncore/serialization/children-variants.json new file mode 100644 index 0000000..17f6d58 --- /dev/null +++ b/lioncore/serialization/children-variants.json @@ -0,0 +1,89 @@ +{ + "serializationFormatVersion": "1", + "languages": [ + { + "key": "myLanguage", + "version": "2" + } + ], + "nodes": [ + { + "id": "ccc", + "concept": { + "language": "myLanguage", + "version": "2", + "key": "myConceptId" + }, + "properties": {}, + "children": [ + { + "containment": { + "language": "myLanguage", + "version": "2", + "key": "emptyContainmentId" + }, + "children": [] + }, + { + "containment": { + "language": "myLanguage", + "version": "2", + "key": "singleContainmentId" + }, + "children": [ + "cdd" + ] + }, + { + "containment": { + "language": "myLanguage", + "version": "2", + "key": "multiContainmentId" + }, + "children": [ + "cee", + "cff", + "cgg" + ] + } + ], + "references": {}, + "parent": null + }, + { + "id": "cgg", + "concept": { + "language": "myLanguage", + "version": "2", + "key": "differentConceptId" + }, + "properties": {}, + "children": {}, + "references": {}, + "parent": null + }, + { + "id": "cdd", + "concept": { + "language": "myLanguage", + "version": "2", + "key": "otherConceptId" + }, + "properties": {}, + "children": {}, + "references": {} + }, + { + "id": "cee", + "concept": { + "language": "myLanguage", + "version": "2", + "key": "differentConceptId" + }, + "properties": {}, + "children": {}, + "references": {}, + "parent": null + } + ] +} \ No newline at end of file diff --git a/lioncore/serialization/minimal-node.json b/lioncore/serialization/minimal-node.json new file mode 100644 index 0000000..fc34553 --- /dev/null +++ b/lioncore/serialization/minimal-node.json @@ -0,0 +1,23 @@ +{ + "serializationFormatVersion": "1", + "languages": [ + { + "key": "myLanguage", + "version": "2" + } + ], + "nodes": [ + { + "id": "aaa", + "concept": { + "language": "myLanguage", + "version": "2", + "key": "myConceptId" + }, + "properties": {}, + "children": {}, + "references": {}, + "parent": null + } + ] +} \ No newline at end of file diff --git a/lioncore/serialization/minimal.json b/lioncore/serialization/minimal.json new file mode 100644 index 0000000..3410bc1 --- /dev/null +++ b/lioncore/serialization/minimal.json @@ -0,0 +1,5 @@ +{ + "serializationFormatVersion": "1", + "languages": [], + "nodes": [] +} \ No newline at end of file diff --git a/lioncore/serialization/property-variants.json b/lioncore/serialization/property-variants.json new file mode 100644 index 0000000..50fc31d --- /dev/null +++ b/lioncore/serialization/property-variants.json @@ -0,0 +1,101 @@ +{ + "serializationFormatVersion": "1", + "languages": [ + { + "key": "myLanguage", + "version": "2" + } + ], + "nodes": [ + { + "id": "bbb", + "concept": { + "language": "myLanguage", + "version": "2", + "key": "myConceptId" + }, + "properties": [ + { + "property": { + "language": "myLanguage", + "version": "2", + "key": "stringPropertyId" + }, + "value": "my string value" + }, + { + "property": { + "language": "myLanguage", + "version": "2", + "key": "integerPropertyId" + }, + "value": "123" + }, + { + "property": { + "language": "myLanguage", + "version": "2", + "key": "booleanPropertyId" + }, + "value": "true" + }, + { + "property": { + "language": "myLanguage", + "version": "2", + "key": "jsonPropertyId" + }, + "value": "{ \"name\": \"Bob\" }" + }, + { + "property": { + "language": "myLanguage", + "version": "2", + "key": "unsetPropertyId" + }, + "value": null + } + ], + "children": {}, + "references": {}, + "parent": null + }, + { + "id": "21", + "concept": { + "language": "myLanguage", + "version": "2", + "key": "time_to_open" + }, + "properties": [ + { + "property": { + "language": "myLanguage", + "version": "2", + "key": "day" + }, + "value": "tttt" + }, + { + "property": { + "language": "myLanguage", + "version": "2", + "key": "starthour" + }, + "value": "9" + }, + { + "property": { + "language": "myLanguage", + "version": "2", + "key": "endhour" + }, + "value": "5" + } + ], + "children": [], + "references": [], + "parent": null + } + ] +} \ No newline at end of file diff --git a/lioncore/serialization/reference-variants.json b/lioncore/serialization/reference-variants.json new file mode 100644 index 0000000..aa4fc46 --- /dev/null +++ b/lioncore/serialization/reference-variants.json @@ -0,0 +1,100 @@ +{ + "serializationFormatVersion": "1", + "languages": [ + { + "key": "myLanguage", + "version": "2" + } + ], + "nodes": [ + { + "id": "ddd", + "concept": { + "language": "myLanguage", + "version": "2", + "key": "myConceptId" + }, + "properties": {}, + "children": {}, + "references": [ + { + "reference": { + "language": "myLanguage", + "version": "2", + "key": "emptyReferenceId" + }, + "targets": [] + }, + { + "reference": { + "language": "myLanguage", + "version": "2", + "key": "singleReferenceId" + }, + "targets": [ + { + "resolveInfo": "some name", + "reference": "dee" + } + ] + }, + { + "reference": { + "language": "myLanguage", + "version": "2", + "key": "multiReferenceId" + }, + "targets": [ + { + "resolveInfo": "self-reference", + "reference": "ddd" + }, + { + "resolveInfo": "only resolve info", + "reference": null + } + ] + }, + { + "reference": { + "language": "myLanguage", + "version": "2", + "key": "noResolveInfoReferenceId" + }, + "targets": [ + { + "resolveInfo": null, + "reference": "dee" + } + ] + }, + { + "reference": { + "language": "myLanguage", + "version": "2", + "key": "neitherResolveInfoNorReferenceId" + }, + "targets": [ + { + "resolveInfo": null, + "reference": null + } + ] + } + ], + "parent": null + }, + { + "id": "dee", + "concept": { + "language": "myLanguage", + "version": "2", + "key": "differentConceptId" + }, + "properties": {}, + "children": {}, + "references": {}, + "parent": null + } + ] +} \ No newline at end of file diff --git a/lioncore/serialization/references.adoc b/lioncore/serialization/references.adoc new file mode 100644 index 0000000..147b51b --- /dev/null +++ b/lioncore/serialization/references.adoc @@ -0,0 +1,100 @@ += References + +[[ref-resolve-null]] +== Meaning and rationale of `null` values for reference id and resolveInfo + +Based on{fn-org36-null} + +NOTE: We only consider low-level model structure here. +If we had a reference of type `Car`, but the id points to an existing `Wheel`, we would _still_ consider the reference valid on this low level. + +In the following matrix, the columns describe _reference_, the rows _resolveInfo_. + +reference: + +* _valid_ means there it is known that a node with the target id exists. +Undefined whether the targeted node is part of the same model fragment, known locally, or only known to the repository. +* _unknown_ means we don't know whether a node with the target id exists. +* _invalid_ means we know that no node with the target id exists. + +resolveInfo: + +* _uniquely resolvable_ means that the resolver[1] can find exactly one existing node that could match the given resolve info. +* _ambiguously resolvable_ means that the resolver[1] can find more than one existing node that could match the given resolve info. +* _non-resolvable_ means that the resolver[1] can not find any existing node that could match the given resolve info. + +ad [1]: It's currently undefined who the resolver is. +We just assume it can somehow interpret the resolve info, and can return [0..*] valid target nodes. + +[%header,cols=">h,<,<,<,<"] +|=== +|id → + +resolveInfo ↓ +^|non-null, valid +^|non-null, unknown +^|non-null, invalid +^|null + +|non-null, uniquely resolvable +|happy case +|transient, resolvable +|brittle +|brittle + +|non-null, ambiguously resolvable +|mostly happy +|transient +|external selection required +|external selection required + +|non-null, non-resolvable +|mostly happy +|transient +|external help required +|external help required + +|null +|mostly happy +|transient +|broken +|broken +|=== + +.Happy case +We know and can reach the target node of the reference. +We also have information how to find the target in case the target is not reachable (e.g. because it has been deleted). + +.Transient +We know a target node id, but don't know yet whether that node exists. + +.Resolvable +Either through node id or resolveInfo, we're sure we can eventually find our target. + +.Brittle +We cannot find the target node by id, but via resolveInfo. +However, resolveInfo might stop working at some point (e.g. if the target gets renamed before resolving the nodeInfo). + +.Mostly happy +We know and can reach the target node of the reference. +But we could not re-establish the reference if the target is not reachable (e.g. because the user cuts+pastes the target node, and the pasted one gets a new id). + +.External selection required +We don't know the target node. +However, we can present the user with a list of options to chose from. +We populate this list with the potential targets of the resolveInfo. + +.External help required +We don't know the target node, and cannot make sense of resolveInfo. +The user might use the resolveInfo to find the actual target. + +.Broken +We have no technical way to find the target node, or meaningful ways to support the user to find it. + +[NOTE] +==== +Instead of the user helping out, we might also infer the same information from language specifics. + +Example: Assume a function with only one parameter. +If we had a reference that can only target a parameter, we can infer that target to be the one parameter. +In practice, that means scoping could help us out here (but that's out of scope as of the first remark above). +==== \ No newline at end of file diff --git a/lioncore/serialization/serialization.adoc b/lioncore/serialization/serialization.adoc new file mode 100644 index 0000000..48fd763 --- /dev/null +++ b/lioncore/serialization/serialization.adoc @@ -0,0 +1,434 @@ +include::../issue-footnotes.adoc[] + +:m3: ../metametamodel/metametamodel +:fn-mof: footnote:mof[https://en.wikipedia.org/wiki/Meta-Object_Facility[Meta-Object Facility], also known as M3 model] + += LIonWeb Serialization Format + +== Conventions used in this document +* _italic_ words refer to concepts defined by JSON. +* *bold* words refer to concepts defined in this document. +* `monospaced` words describe verbatim contents of the serialization. +* Footnotes refer to more discussions and rationale, but are non-normative. + +== Design Goals +We do not take any measures to reduce the amount of transmitted data.{fn-org73} + +== Description +LIonWeb node serialization format is defined in JSON (https://datatracker.ietf.org/doc/html/rfc8259[RFC 8259]). + +== Overview of structures + +[plantuml, serialization, svg] +---- +include::serialization.puml[] +---- + +=== Root structure + +[[SerializationChunk]] +Root level MUST be an _object_ with three members, called *serialization chunk*. + +##TODO: Are more members allowed?{fn-org67}## + +[[SerializationChunk.serializationFormatVersion]] +The first member MUST be _key_ `serializationFormatVersion` with a _string_ _value_.{fn-org58} +The value MUST be a decimal integer (without leading or trailing whitespace) describing the serialization format version used to create the processed document, according to <>. + +[[SerializationChunk.languages]] +The second member MUST be _key_ `languages` with an _array_ _value_.{fn-org76}{fn-org78} +Each _element_ in the value array MUST adhere to <>. +The order of _elements_ is undefined. +_elements_ MUST contain all language/version referred to by any <> in the processed document. +Each _element_ must be unique with respect to all its _members_. + +[[SerializationChunk.nodes]] +The third member MUST be _key_ `nodes` with an _array_ _value_.{fn-org33} +Each _element_ in the value array MUST adhere to <>. +The order of _elements_ is undefined. +Each _element_ must be unique with respect to the value of its _key_ `id`. + +[[language]] +=== Language structure +[[UsedLanguage]] +Each *used language* MUST be an _object_.{fn-org129} +The order of _members_ is undefined. + +The _object_ MUST contain the following _members_:{fn-org76} + +* [[UsedLanguage.key]] _key_ `key` with _string_ _value_, adhering to <>. +* [[UsedLanguage.version]] _key_ `version` with _string_ _value_, adhering to <>. + +[[language-key]] +==== Language key +A _string_ according to <<{m3}.adoc#keys, Key spec>>. +Refers to the <<{m3}.adoc#IKeyed.key, key>> of the language. + +[[language-version]] +==== Language version +A _string_ with any contents{fn-org128}{fn-org130}, MUST NOT be empty.{fn-org92} +Refers to the <<{m3}.adoc#Language.version, version>> of the language. + +[[meta-pointer]] +=== Meta-pointer +[[MetaPointer]] +A *meta-pointer* is a reference from M1 to M2.{fn-org89}{fn-mof} +It's used at several places within <>. + +Each meta-pointer MUST be an _object_. +The order of _members_ is undefined. + +The _object_ MUST contain the following _members_: + +* [[MetaPointer.lanuage]] _key_ `language` with _string_ _value_, adhering to <>. +* [[MetaPointer.version]] _key_ `version` with _string_ _value_, adhering to <>. +* [[MetaPointer.key]] _key_ `key` with _string_ _value_ according to <<{m3}.adoc#keys, Keys spec>>. +Refers to some <<{m3}.adoc#IKeyed, element in the language>>. +Which element exactly is specified for each usage of meta-pointer. + +[[node]] +=== Node structure +[[Node]] +Each *node* MUST be an _object_.{fn-org37} +The order of _members_ is undefined. + +The _object_ MUST contain the following _members_:{fn-org59}{fn-java33}{fn-org55} + +* [[Node.id]] _key_ `id` with _string_ _value_, adhering to <>. +* [[Node.concept]] _key_ `concept`{fn-org37-name} with _object_ _value_, adhering to <>. + The *meta-pointer*'s ``key``'s _value_ refers to the <<{m3}.adoc#IKeyed.key, *key*>> of the <<{m3}.adoc#Concept, *Concept*>> this *node* is an instance of. +* [[Node.properties]] _key_ `properties` with _array_ _value_, each _element_ adhering to <>. +The order of _elements_ is undefined. +* [[Node.children]] _key_ `children`{fn-org55-name-children} with _array_ _value_, each _element_ adhering to <>. +The order of _elements_ is undefined. +* [[Node.references]] _key_ `references`{fn-org55-name-references} with _array_ _value_, each _element_ adhering to <>. +The order of _elements_ is undefined. +* [[Node.parent]] _key_ `parent` with _string_ or _null_ _value_, adhering to <>. + +##TODO: How to store invalid text?{fn-org62}## + + +[[id]] +==== Id value +A _string_ according to <<{m3}.adoc#identifiers, Identifier spec>>. +Defines the *id* of this *node*. + + +[[property]] +==== Property +[[Property]] +Each *property* MUST be an _object_. +The order of _members_ is undefined. + +The _object_ MUST contain the following _members_: + +* [[Property.property]] _key_ `property` with _object_ _value_, adhering to <>. + The *meta-pointer*'s ``key``'s _value_ refers to the <<{m3}.adoc#IKeyed.key, *key*>> of the <<{m3}.adoc#Property, *Property*>> this *property* is an instance of. +* [[Property.value]] _key_ `value` with _value_ as one of +** _string_{fn-org34} containing the value of the property referenced by the `property`. +Refer to <> for the specification of the value format. +CAN be an empty _string_. +** _null_ to explicitly specify the property to be unset. + + +[[child]] +==== Child +[[Child]] +Each *child* MUST be an _object_. +The order of _members_ is undefined. + +The _object_ MUST contain the following _members_: + +* [[Child.containment]] _key_ `containment` with _object_ _value_, adhering to <>. +The *meta-pointer*'s ``key``'s _value_ refers to the <<{m3}.adoc#IKeyed.key, *key*>> of the <<{m3}.adoc#Containment, *Containment*>> this *child* is an instance of. +* [[Child.children]] _key_ `children` with _array_ _value_ with _string_ _elements_. +Each _element_ adheres to <<{m3}.adoc#identifiers, Identifier spec>>, and refers to the *id* of the contained *node*. +The order of _elements_ is undefined. ++ +NOTE: Each *child* element is the inverse relation of *parent*. ++ +NOTE: The children *node* CAN be contained in the processed document, but also CAN be outside the processed document (i.e. not contained in the processed document). + +[[reference]] +==== Reference +[[Reference]] +Each *reference* MUST be an _object_. +The order of _members_ is undefined. + +The _object_ MUST contain the following _members_: + +* [[Reference.reference]] _key_ `reference` with _object_ _value_, adhering to <>. +The *meta-pointer*'s ``key``'s _value_ refers to the <<{m3}.adoc#IKeyed.key, *key*>> of the <<{m3}.adoc#Reference, *Reference*>> this *reference* is an instance of. +* [[Reference.targets]] _key_ `targets` with __object_ _elements_. +Each _element_ MUST have the following _members_ in undefined order:{fn-org55-name-references} +** [[Reference.reference.resolveInfo]] _key_ `resolveInfo`{fn-org36} with _value_ as one of: +*** _string_ containing *resolveInfo*, a textual hint that might be used to find the target *node* of this reference. +Interface <<{m3}.adoc#INamed, INamed>> SHOULD be used as a default, if available. +The exact value depends on the implementation. +CAN be an empty _string_. +*** _null_ if no *resolveInfo* is available. + +** [[Reference.reference.reference]] _key_ `reference`{fn-org35} with _value_ as one of: +*** _string_ according to <<{m3}.adoc#identifiers, Identifier spec>>. +Refers to the *id* of the target *node*. ++ +NOTE: The referred *node* CAN be contained in the processed document, but also CAN be outside the processed document (i.e. not contained in the processed document). +*** _null_ if the *id* of the target *node* is not known. + +[[parent]] +==== Parent +One of + +* _string_ according to <<{m3.acoc}#identifiers, Identifier spec>>. +Refers to the *id* of the *node* containing this *node*. ++ +NOTE: *parent* is the inverse relation of one *child*. ++ +NOTE: The referred *node* CAN be contained in the processed document, but also CAN be outside the processed document (i.e. not contained in the processed document). + +* _null_ if +** This *node* is a *root node*, i.e. this node does not have a parent. +** This serialization is sent as an update request. + +[[property-values]] +=== Property serialization +All property values MUST be serialized as JSON _string_.{fn-org34}{fn-org9}. +An unset property CAN be serialized as JSON _null_. + +==== String +<<{m3}.adoc#String, LIonCore Strings>> might be any string, of any length, including (but not limited to): + +* empty string: `""` +* only containing whitespace: `" "` +* containing escaped characters as per JSON spec: `"They said:\n \"Hello!\""` +* containing extended Unicode characters: `"😐"` +* containing escaped Unicode characters: `"\uD83D\uDE10"` + +==== Boolean +<<{m3}.adoc#Boolean, LIonCore Booleans>> MUST be encoded as exactly one of these JSON _strings_: + +* `"true"` +* `"false"` + +Booleans MUST NOT be encoded with leading or trailing whitespace, uppercase characters, short forms (like `t` or `f`), or decimal representation (like `1`, `0`, `-1`). + +==== Integer +<<{m3}.adoc#Integer, LIonCore Integers>> MUST be encoded as JSON _string_. + +* Integers MUST be represented in base-10. +* The digits CAN be prefixed with either `+` (plus) or `-` (minus).{fn-org100} +* Integers MUST NOT be prefixed by leading zeros. +* Integers CAN contain value zero with any prefix, i.e. `0`, `-0`, or `+0`. +* Integers MUST NOT contain leading or trailing whitespace. +* LIonWeb does NOT limit the range of the integer value.{fn-org149} + An implementation MAY refuse a model containing an integer value outside the supported range. + +.Examples of valid Integer encodings + +* `"0"` +* `"+0"` +* `"-0"` +* `"123"` +* `"-100000"` +* `"+999"` +* `"100000000200000000300000000400000000500000000600000000700000000800000000900000000999999999"` +* `"-999999999900000000800000000700000000600000000500000000400000000300000000200000000100000000"` + +.Examples of invalid Integer encodings + +* `""` +* `123` +* `-1` +* `"+-0"` +* `"++1"` +* `"00002"` +* `"0xAA12"` +* `" 5"` +* `"-6 "` + +==== JSON +<<{m3}.adoc#JSON, LIonCore JSON>> MUST be encoded as JSON _string_. +All double quotes, line breaks, etc. MUST be escaped to form a proper JSON _string_. +The value MUST adhere to JSON spec (RFC 8259). + +.Valid example +`"{ \"key\": \"my value\",\n\"myArray\": [1, -2, true] }"` + +.Invalid example +`{ "key": "my value", "myArray": [1, -2, true] }` + +==== Enumeration Literals +<<{m3}.adoc#EnumerationLiteral, LIonCore Enumeration literals>> MUST be encoded as JSON _string_ _value_ according to <<{m3}.adoc#keys, Key spec>>. +MUST refer to the <<{m3}.adoc#IKeyed.key, key>> of an <<{m3}.adoc#EnumerationLiteral, EnumerationLiteral>> of the <<{m3}.adoc#Enumeration, Enumeration>> defined as <<{m3}.adoc#Property.type, type>> of this *Property*.{fn-org128} + +== Examples + +=== Minimal +[source,json] +---- +include::minimal.json[] +---- + +=== Minimal node +[source,json] +---- +include::minimal-node.json[] +---- + +=== Property variants + +For this example, we need to define an enumeration and a concept that uses the enumeration. + +NOTE: The format used in this example is non-normative. + +Assume this enumeration: +[source] +---- +enumeration DaysOfWeek [id 23, key days-of-week] + + literal Monday [id 34, key monday] + literal Tuesday [id 2, key tttt] + literal Wednesday [id 55, key 12398712] +---- + +And this concept: +[source] +---- +concept OpeningTime [id 44, key time_to_open] + property day: DaysOfWeek [id 42, key day] + property startHour: Integer [id 22, key starthour] + property endHour: Integer [id 89, key endhour] +---- + +[source,json] +---- +include::property-variants.json[] +---- + +=== Children variants +[source,json] +---- +include::children-variants.json[] +---- + +*node* with *id* `cff` is outside the processed document. + +=== Reference variants +We support different kinds of targets.{fn-org57} +[source,json] +---- +include::reference-variants.json[] +---- + + +[[versions]] +== Versions +=== 1 +Initial version. + + +[[possible-values]] +== Possible values for `properties`, `children`, and `references` +Only bold entries are valid.{fn-java33} + +[%header,cols="1a,1,1,1"] +|=== +|1 A + +Contents +|B + +``properties: {``_ _ _``}`` +|C + +``children: {``_ _ _``}`` +|D + +``references: {``_ _ _``}`` + +|2 `"a": "b"` +|*property with id `a` has value `b`* +.4+.^|`children` value must be array +.4+.^|`references` value must be array + +|3 `"c": ""` +|*property with id `c` has value (empty string)* +// |`children` value must be array +// |`references` value must be array + +|4 `"d": " "` +|*property with id `d` has value ` `(one space)* +// |`children`value must be array +// |`references`value must be array + +|5 `"e": null` +|*property with id `e` has no value* +// |`children` value must be array +// |`references` value must be array + +|6 (key `f` not present) +|*property with id `f` has no value* +|*containment with id `f` does not contain any nodes* +|*reference with id `f` does not point to any nodes* + +|7 `"g": []` +.9+.^|`properties` value must be string +|*containment with id `g` does not contain any nodes* +|*reference with id `g` does not point to any nodes* + +|8 `"h": [ "i" ]` +// |`properties`value must be string +|*containment with id `h` contains node with id`i`* +|`references` value array element must be object + +|9 + +[source%nowrap] +---- +"j": [ + { + "resolveInfo": "k", + "reference": "l" + } +] +---- +// |`properties` value must be string +.2+.^|`children` value array element must be string +|*reference with id `j` points to node with id `l`, re-binding supported by text `k`* + +|10 `"m": [ null ]` +// |`properties` value must be string +// |`children` value array element must be a string +|`references` value array element must be an object + +|11 `"n": true` +// |`properties` value must be string +.5+.^|`children` value must be array +.5+.^|`references` value must be array + +|12 `"o": 12` +// |`properties` value must be string +// |`children` value must be array +// |`references` value must be array + +|13 `"p": 34.56` +// |`properties` value must be string +// |`children` value must be array +// |`references` value must be array + +|14 `"q": {}` +// |`properties` value must be string +// |`children` value must be array +// |`references` value must be array + +|15 `"r": {`...`}` +// |`properties` value must be string +// |`children` value must be array +// |`references` value must be array + +|16 `"s": foo` +3.2+^.^|JSON syntax error +// |JSON syntax error +// |JSON syntax error + +|17 `"t": undefined` +// |JSON syntax error +// |JSON syntax error +// |JSON syntax error +|=== diff --git a/lioncore/serialization/serialization.puml b/lioncore/serialization/serialization.puml new file mode 100644 index 0000000..7f13269 --- /dev/null +++ b/lioncore/serialization/serialization.puml @@ -0,0 +1,63 @@ +@startuml +'title Serialization Format + +hide empty members + +class SerializationChunk { + serializationFormatVersion: String +} + +SerializationChunk *--> "0..*" UsedLanguage: languages + +class UsedLanguage { + key: Id + version: String +} + +SerializationChunk *--> "0..*" Node: nodes + +class Node { + id: Id + parent: Id +} + +Node *--> "1" MetaPointer: concept + +class MetaPointer { + language: Id + version: String + key: Id +} + +Node *--> "0..*" Child: children + +class Child { + children: String[] +} + +Child *--> "1" MetaPointer: containment + +Node *--> "0..*" Property: properties + +class Property { + value: String +} + +Property *--> "1" MetaPointer: property + + +Node *--> "0..*" Reference: references + +class Reference { +} + +Reference *--> "1" MetaPointer: reference + +Reference *--> "0..*" ReferenceTarget: targets + +class ReferenceTarget { + reference: Id + resolveInfo: String +} + +@enduml \ No newline at end of file