@purview-dev/astroc4 0.0.0-stage → 1.0.0-prerelease.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +9 -0
- package/README.md +179 -2
- package/package.json +96 -4
- package/src/components/DiagramFrame.astro +72 -0
- package/src/components/DiagramShell.astro +121 -0
- package/src/components/ErrorBoundary.tsx +52 -0
- package/src/components/LikeC4Fence.astro +62 -0
- package/src/components/LikeC4InlineView.tsx +67 -0
- package/src/components/LikeC4ProjectView.tsx +153 -0
- package/src/components/LikeC4View.astro +80 -0
- package/src/components/LoadingPlaceholder.astro +67 -0
- package/src/components/icon-source.ts +68 -0
- package/src/components/labels.ts +62 -0
- package/src/components/render-icon.tsx +41 -0
- package/src/components/utils.ts +69 -0
- package/src/expressive-code.d.mts +28 -0
- package/src/expressive-code.mjs +46 -0
- package/src/fences.mjs +288 -0
- package/src/grammar/langium.mjs +559 -0
- package/src/grammar/like-c4.langium +1357 -0
- package/src/grammar/likec4.tmLanguage.json +327 -0
- package/src/grammar/source.mjs +410 -0
- package/src/grammar/textmate.mjs +439 -0
- package/src/index.d.mts +64 -0
- package/src/index.mjs +228 -0
- package/src/translations.mjs +33 -0
- package/src/types.d.ts +12 -0
|
@@ -0,0 +1,1357 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
//
|
|
3
|
+
// Copyright (c) 2023-2026 Denis Davydkov
|
|
4
|
+
// Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
5
|
+
//
|
|
6
|
+
// Portions of this file have been modified by NVIDIA CORPORATION & AFFILIATES.
|
|
7
|
+
|
|
8
|
+
grammar LikeC4
|
|
9
|
+
|
|
10
|
+
entry LikeC4Grammar:
|
|
11
|
+
(
|
|
12
|
+
imports+=ImportsFromPoject |
|
|
13
|
+
specifications+=SpecificationRule |
|
|
14
|
+
models+=Model |
|
|
15
|
+
views+=ModelViews |
|
|
16
|
+
globals+=Globals |
|
|
17
|
+
deployments+=ModelDeployments |
|
|
18
|
+
diffs+=ModelDiff |
|
|
19
|
+
likec4lib+=LikeC4Lib
|
|
20
|
+
)*
|
|
21
|
+
;
|
|
22
|
+
|
|
23
|
+
// Lib -------------------------------------
|
|
24
|
+
LikeC4Lib:
|
|
25
|
+
'likec4lib' '{'
|
|
26
|
+
'icons' '{'
|
|
27
|
+
(icons+=LibIcon)+
|
|
28
|
+
'}'
|
|
29
|
+
'}';
|
|
30
|
+
|
|
31
|
+
LibIcon:
|
|
32
|
+
name=IconId;
|
|
33
|
+
|
|
34
|
+
// Specification -------------------------------------
|
|
35
|
+
|
|
36
|
+
ElementKind:
|
|
37
|
+
name=Id;
|
|
38
|
+
Tag:
|
|
39
|
+
name=Id;
|
|
40
|
+
RelationshipKind:
|
|
41
|
+
name=Id;
|
|
42
|
+
CustomColor:
|
|
43
|
+
name=CustomColorId;
|
|
44
|
+
DeploymentNodeKind:
|
|
45
|
+
name=Id;
|
|
46
|
+
|
|
47
|
+
SpecificationRule:
|
|
48
|
+
name='specification' '{'
|
|
49
|
+
(
|
|
50
|
+
elements+=SpecificationElementKind |
|
|
51
|
+
tags+=SpecificationTag |
|
|
52
|
+
relationships+=SpecificationRelationshipKind |
|
|
53
|
+
colors+=SpecificationColor |
|
|
54
|
+
deploymentNodes+=SpecificationDeploymentNodeKind
|
|
55
|
+
)*
|
|
56
|
+
'}';
|
|
57
|
+
|
|
58
|
+
SpecificationElementKind:
|
|
59
|
+
'element' kind=ElementKind ('{'
|
|
60
|
+
tags=Tags?
|
|
61
|
+
props+=(
|
|
62
|
+
SpecificationElementStringProperty |
|
|
63
|
+
LinkProperty |
|
|
64
|
+
DescriptionFileProperty |
|
|
65
|
+
ElementStyleProperty
|
|
66
|
+
)*
|
|
67
|
+
'}')?;
|
|
68
|
+
|
|
69
|
+
SpecificationElementStringProperty:
|
|
70
|
+
key=('title' | 'description' | 'technology' | 'notation' | 'summary') ':'? value=MarkdownOrString ';'?;
|
|
71
|
+
|
|
72
|
+
SpecificationDeploymentNodeKind:
|
|
73
|
+
'deploymentNode' kind=DeploymentNodeKind ('{'
|
|
74
|
+
tags=Tags?
|
|
75
|
+
props+=(
|
|
76
|
+
SpecificationElementStringProperty |
|
|
77
|
+
LinkProperty |
|
|
78
|
+
DescriptionFileProperty |
|
|
79
|
+
ElementStyleProperty
|
|
80
|
+
)*
|
|
81
|
+
'}')?;
|
|
82
|
+
|
|
83
|
+
SpecificationTag:
|
|
84
|
+
'tag' tag=Tag ('{'
|
|
85
|
+
('color' (ColorRef | color=ColorLiteral))?
|
|
86
|
+
'}')?;
|
|
87
|
+
|
|
88
|
+
SpecificationColor:
|
|
89
|
+
'color' name=CustomColor color=ColorLiteral;
|
|
90
|
+
|
|
91
|
+
SpecificationRelationshipKind:
|
|
92
|
+
'relationship' kind=RelationshipKind ('{'
|
|
93
|
+
tags=Tags?
|
|
94
|
+
props+=(
|
|
95
|
+
LinkProperty |
|
|
96
|
+
DescriptionFileProperty |
|
|
97
|
+
RelationshipStyleProperty |
|
|
98
|
+
SpecificationRelationshipStringProperty |
|
|
99
|
+
MultipleProperty
|
|
100
|
+
)*
|
|
101
|
+
'}')?
|
|
102
|
+
;
|
|
103
|
+
|
|
104
|
+
SpecificationRelationshipStringProperty:
|
|
105
|
+
key=('title' | 'description' | 'technology' | 'notation') ':'? value=MarkdownOrString ';'?;
|
|
106
|
+
|
|
107
|
+
// Imports -------------------------------------
|
|
108
|
+
|
|
109
|
+
ImportsFromPoject:
|
|
110
|
+
'import' ( '{' imports=Imported '}' | imports=Imported) 'from' project=String ';'?
|
|
111
|
+
;
|
|
112
|
+
|
|
113
|
+
Imported:
|
|
114
|
+
imported=[Element:Id] ({infer Imported.prev=current} ',' imported=[Element:Id])* ';'?
|
|
115
|
+
;
|
|
116
|
+
|
|
117
|
+
// Model -------------------------------------
|
|
118
|
+
|
|
119
|
+
// Allow use spaces and commas in tags
|
|
120
|
+
Tags:
|
|
121
|
+
(values+=TagRef)+ ({infer Tags.prev=current} ',' (values+=TagRef)*)* ';'?
|
|
122
|
+
;
|
|
123
|
+
|
|
124
|
+
Model:
|
|
125
|
+
name='model' '{'
|
|
126
|
+
elements+=(ModelElement)*
|
|
127
|
+
'}'
|
|
128
|
+
;
|
|
129
|
+
|
|
130
|
+
ModelElement:
|
|
131
|
+
ExtendElementOrRelation |
|
|
132
|
+
Relation<true> |
|
|
133
|
+
Element
|
|
134
|
+
;
|
|
135
|
+
|
|
136
|
+
Element:
|
|
137
|
+
(
|
|
138
|
+
kind=[ElementKind] name=Id |
|
|
139
|
+
name=Id Eq kind=[ElementKind]
|
|
140
|
+
)
|
|
141
|
+
(props+=String // title
|
|
142
|
+
(props+=String // summary
|
|
143
|
+
(props+=String // technology
|
|
144
|
+
(props+=String)? // tags (ignored by likec4, but still parsed for Structurizr compatibility)
|
|
145
|
+
)?
|
|
146
|
+
)?
|
|
147
|
+
)?
|
|
148
|
+
body=ElementBody?
|
|
149
|
+
;
|
|
150
|
+
|
|
151
|
+
ElementBody:
|
|
152
|
+
'{'
|
|
153
|
+
tags=Tags?
|
|
154
|
+
props+=ElementProperty*
|
|
155
|
+
elements+=(
|
|
156
|
+
Relation<false> |
|
|
157
|
+
Element
|
|
158
|
+
)*
|
|
159
|
+
'}'
|
|
160
|
+
;
|
|
161
|
+
|
|
162
|
+
ElementProperty:
|
|
163
|
+
ElementStringProperty |
|
|
164
|
+
ElementStyleProperty |
|
|
165
|
+
LinkProperty |
|
|
166
|
+
DescriptionFileProperty |
|
|
167
|
+
IconProperty |
|
|
168
|
+
MetadataProperty;
|
|
169
|
+
|
|
170
|
+
ElementStringProperty:
|
|
171
|
+
key=('title' | 'description' | 'technology' | 'summary') ':'? value=MarkdownOrString ';'?;
|
|
172
|
+
|
|
173
|
+
ExtendElementOrRelation:
|
|
174
|
+
'extend' (
|
|
175
|
+
{infer ExtendRelation}
|
|
176
|
+
source=FqnRef
|
|
177
|
+
RelationConnector
|
|
178
|
+
target=FqnRef
|
|
179
|
+
title=String?
|
|
180
|
+
body=ExtendRelationBody |
|
|
181
|
+
{infer ExtendElement}
|
|
182
|
+
element=StrictFqnElementRef
|
|
183
|
+
body=ExtendElementBody
|
|
184
|
+
)
|
|
185
|
+
;
|
|
186
|
+
|
|
187
|
+
ExtendElementBody:
|
|
188
|
+
'{'
|
|
189
|
+
tags=Tags?
|
|
190
|
+
props+=ExtendElementProperty*
|
|
191
|
+
|
|
192
|
+
elements+=(
|
|
193
|
+
Relation<false> |
|
|
194
|
+
Element
|
|
195
|
+
)*
|
|
196
|
+
'}'
|
|
197
|
+
;
|
|
198
|
+
|
|
199
|
+
ExtendElementProperty:
|
|
200
|
+
LinkProperty |
|
|
201
|
+
MetadataProperty;
|
|
202
|
+
|
|
203
|
+
ExtendRelationBody:
|
|
204
|
+
'{'
|
|
205
|
+
tags=Tags?
|
|
206
|
+
props+=ExtendRelationProperty*
|
|
207
|
+
'}'
|
|
208
|
+
;
|
|
209
|
+
|
|
210
|
+
ExtendRelationProperty:
|
|
211
|
+
LinkProperty |
|
|
212
|
+
MetadataProperty;
|
|
213
|
+
|
|
214
|
+
// Hack, to strictly enforce resolution of model elements ONLY (in active scope)
|
|
215
|
+
interface ElementRef {
|
|
216
|
+
modelElement: FqnRef;
|
|
217
|
+
}
|
|
218
|
+
ElementRef returns ElementRef:
|
|
219
|
+
modelElement=FqnRef;
|
|
220
|
+
|
|
221
|
+
interface StrictFqnElementRef {
|
|
222
|
+
parent?: StrictFqnElementRef;
|
|
223
|
+
el: @Element;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
StrictFqnElementRef returns StrictFqnElementRef:
|
|
227
|
+
el=[Element:Id] ({StrictFqnElementRef.parent=current} StickyDot el=[Element:Id])*;
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
type ModelReferenceable = Element | Imported;
|
|
231
|
+
type Referenceable = DeploymentNode | DeployedInstance | Element | Imported;
|
|
232
|
+
|
|
233
|
+
interface FqnRef {
|
|
234
|
+
parent?: FqnRef;
|
|
235
|
+
value: @Referenceable;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
interface StrictFqnRef {
|
|
239
|
+
parent?: StrictFqnRef;
|
|
240
|
+
value: @Referenceable;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// Reference to Elements in logical or deployment model
|
|
244
|
+
// Scope computation is based on the parent element:
|
|
245
|
+
// - If parent is DeploymentNode, then it can reference nested DeploymentNodes and DeployedInstances
|
|
246
|
+
// - If parent is DeployedInstance, then it can reference nested Element
|
|
247
|
+
// - If parent is Element, then it can reference nested Element
|
|
248
|
+
// Mix of DeploymentRef and ElementRef
|
|
249
|
+
FqnRef returns FqnRef:
|
|
250
|
+
value=[Referenceable:Id] ({FqnRef.parent=current} StickyDot value=[Referenceable:Id])*
|
|
251
|
+
;
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
// Strict reference allows only direct children of parent
|
|
255
|
+
StrictFqnRef returns StrictFqnRef:
|
|
256
|
+
value=[Referenceable:Id] ({StrictFqnRef.parent=current} StickyDot value=[Referenceable:Id])*
|
|
257
|
+
;
|
|
258
|
+
|
|
259
|
+
Relation<isExplicit>:
|
|
260
|
+
(<isExplicit> source=FqnRef | <!isExplicit> source=FqnRef?)
|
|
261
|
+
RelationConnector
|
|
262
|
+
target=FqnRef
|
|
263
|
+
(title=String // title
|
|
264
|
+
(description=String // description
|
|
265
|
+
(technology=String)?
|
|
266
|
+
)?
|
|
267
|
+
)?
|
|
268
|
+
tags=Tags?
|
|
269
|
+
body=RelationBody?
|
|
270
|
+
;
|
|
271
|
+
|
|
272
|
+
fragment RelationConnector:
|
|
273
|
+
dotKind=RelationKindDotRef |
|
|
274
|
+
'-[' kind=[RelationshipKind] (isBidirectional?=']<->' | ']->') |
|
|
275
|
+
isBidirectional?='<->' |
|
|
276
|
+
'->'
|
|
277
|
+
;
|
|
278
|
+
|
|
279
|
+
RelationBody:
|
|
280
|
+
'{'
|
|
281
|
+
tags=Tags?
|
|
282
|
+
props+=RelationProperty*
|
|
283
|
+
'}'
|
|
284
|
+
;
|
|
285
|
+
|
|
286
|
+
RelationProperty:
|
|
287
|
+
RelationStringProperty |
|
|
288
|
+
RelationNavigateToProperty |
|
|
289
|
+
RelationStyleProperty |
|
|
290
|
+
LinkProperty |
|
|
291
|
+
DescriptionFileProperty |
|
|
292
|
+
MetadataProperty
|
|
293
|
+
;
|
|
294
|
+
|
|
295
|
+
RelationStringProperty:
|
|
296
|
+
key=('title' | 'technology' | 'description') ':'? value=MarkdownOrString ';'?;
|
|
297
|
+
|
|
298
|
+
RelationStyleProperty:
|
|
299
|
+
key='style' '{'
|
|
300
|
+
props+=RelationshipStyleProperty*
|
|
301
|
+
'}'
|
|
302
|
+
;
|
|
303
|
+
|
|
304
|
+
MetadataProperty:
|
|
305
|
+
'metadata' MetadataBody
|
|
306
|
+
;
|
|
307
|
+
|
|
308
|
+
MetadataBody:
|
|
309
|
+
'{'
|
|
310
|
+
props+=(MetadataAttribute)*
|
|
311
|
+
'}'
|
|
312
|
+
;
|
|
313
|
+
|
|
314
|
+
MetadataAttribute:
|
|
315
|
+
key=Id ':'? (value=MetadataValue | boolValue=BOOLEAN) ';'?
|
|
316
|
+
;
|
|
317
|
+
|
|
318
|
+
MetadataValue:
|
|
319
|
+
MarkdownOrString | MetadataArray
|
|
320
|
+
;
|
|
321
|
+
|
|
322
|
+
MetadataArray:
|
|
323
|
+
'[' values+=(MarkdownOrString) (',' values+=(MarkdownOrString))* ']'
|
|
324
|
+
;
|
|
325
|
+
|
|
326
|
+
// Views -------------------------------------
|
|
327
|
+
|
|
328
|
+
ModelViews:
|
|
329
|
+
name='views' folder=String? '{' (
|
|
330
|
+
views+=LikeC4ViewRule |
|
|
331
|
+
styles+=ViewRuleStyleOrGlobalRef
|
|
332
|
+
)*
|
|
333
|
+
'}';
|
|
334
|
+
|
|
335
|
+
type LikeC4View = ElementView | DynamicView | DeploymentView;
|
|
336
|
+
LikeC4ViewRule returns LikeC4View:
|
|
337
|
+
DynamicView |
|
|
338
|
+
DeploymentView |
|
|
339
|
+
ElementView;
|
|
340
|
+
|
|
341
|
+
ElementView:
|
|
342
|
+
'view' name=Id? (
|
|
343
|
+
'extends' extends=ElementViewRef |
|
|
344
|
+
'of' viewOf=ElementRef
|
|
345
|
+
)?
|
|
346
|
+
body=ElementViewBody?
|
|
347
|
+
;
|
|
348
|
+
|
|
349
|
+
DynamicView:
|
|
350
|
+
'dynamic' 'view' name=Id body=DynamicViewBody?
|
|
351
|
+
;
|
|
352
|
+
|
|
353
|
+
ViewRef:
|
|
354
|
+
view=[LikeC4View];
|
|
355
|
+
|
|
356
|
+
ElementViewRef:
|
|
357
|
+
view=[ElementView];
|
|
358
|
+
|
|
359
|
+
DynamicViewRef:
|
|
360
|
+
view=[DynamicView];
|
|
361
|
+
|
|
362
|
+
ElementViewBody:
|
|
363
|
+
'{'
|
|
364
|
+
tags=Tags?
|
|
365
|
+
props+=ViewProperty*
|
|
366
|
+
rules+=ViewRule*
|
|
367
|
+
'}'
|
|
368
|
+
;
|
|
369
|
+
|
|
370
|
+
DynamicViewBody:
|
|
371
|
+
'{'
|
|
372
|
+
tags=Tags?
|
|
373
|
+
props+=DynamicViewProperty*
|
|
374
|
+
(
|
|
375
|
+
steps+=StepStatement |
|
|
376
|
+
rules+=DynamicViewRule
|
|
377
|
+
)*
|
|
378
|
+
'}'
|
|
379
|
+
;
|
|
380
|
+
|
|
381
|
+
DynamicViewProperty:
|
|
382
|
+
DynamicViewDisplayVariantProperty | ViewProperty
|
|
383
|
+
;
|
|
384
|
+
|
|
385
|
+
DynamicViewDisplayVariantProperty:
|
|
386
|
+
key='variant' value=DynamicViewDisplayVariantValue
|
|
387
|
+
;
|
|
388
|
+
|
|
389
|
+
|
|
390
|
+
type StringProperty =
|
|
391
|
+
ElementStringProperty |
|
|
392
|
+
ViewStringProperty |
|
|
393
|
+
RelationStringProperty |
|
|
394
|
+
MetadataAttribute |
|
|
395
|
+
SpecificationElementStringProperty |
|
|
396
|
+
SpecificationRelationshipStringProperty |
|
|
397
|
+
NotationProperty |
|
|
398
|
+
NotesProperty;
|
|
399
|
+
|
|
400
|
+
type AnyProperty =
|
|
401
|
+
StringProperty |
|
|
402
|
+
ViewProperty |
|
|
403
|
+
DynamicViewProperty |
|
|
404
|
+
ElementProperty |
|
|
405
|
+
RelationProperty |
|
|
406
|
+
RelationshipStyleProperty |
|
|
407
|
+
NavigateToProperty |
|
|
408
|
+
StyleProperty;
|
|
409
|
+
|
|
410
|
+
ViewProperty:
|
|
411
|
+
ViewStringProperty | ViewOrderProperty | LinkProperty | DescriptionFileProperty | ViewRoutingProperty
|
|
412
|
+
;
|
|
413
|
+
|
|
414
|
+
ViewStringProperty:
|
|
415
|
+
key=('title' | 'description') ':'? value=MarkdownOrString ';'?;
|
|
416
|
+
|
|
417
|
+
ViewOrderProperty:
|
|
418
|
+
key='order' value=Number ';'?;
|
|
419
|
+
|
|
420
|
+
ViewRoutingProperty:
|
|
421
|
+
key='routing' ':'? value=EdgeRoutingValue ';'?;
|
|
422
|
+
|
|
423
|
+
EdgeRoutingValue returns string:
|
|
424
|
+
'spline' | 'ortho';
|
|
425
|
+
|
|
426
|
+
ViewLayoutDirection returns string:
|
|
427
|
+
'TopBottom' | 'LeftRight' | 'BottomTop' | 'RightLeft';
|
|
428
|
+
|
|
429
|
+
ViewRule:
|
|
430
|
+
ViewRulePredicate |
|
|
431
|
+
ViewRuleGlobalPredicateRef |
|
|
432
|
+
ViewRuleGroup |
|
|
433
|
+
ViewRuleStyleOrGlobalRef |
|
|
434
|
+
ViewRuleAutoLayout |
|
|
435
|
+
ViewRuleRank
|
|
436
|
+
;
|
|
437
|
+
|
|
438
|
+
ViewRuleRank:
|
|
439
|
+
'rank' value=RankValue? '{'
|
|
440
|
+
targets=FqnExpressions
|
|
441
|
+
'}'
|
|
442
|
+
;
|
|
443
|
+
|
|
444
|
+
RankValue returns string:
|
|
445
|
+
'same' | 'min' | 'max' | 'source' | 'sink';
|
|
446
|
+
|
|
447
|
+
ViewRuleGroup:
|
|
448
|
+
'group' title=String? '{'
|
|
449
|
+
props+=(
|
|
450
|
+
ColorProperty |
|
|
451
|
+
BorderProperty |
|
|
452
|
+
OpacityProperty
|
|
453
|
+
)*
|
|
454
|
+
groupRules+=(
|
|
455
|
+
ViewRulePredicate |
|
|
456
|
+
ViewRuleGlobalPredicateRef |
|
|
457
|
+
ViewRuleGroup
|
|
458
|
+
)*
|
|
459
|
+
'}';
|
|
460
|
+
|
|
461
|
+
DynamicViewRule:
|
|
462
|
+
DynamicViewIncludePredicate |
|
|
463
|
+
DynamicViewGlobalPredicateRef |
|
|
464
|
+
ViewRuleStyleOrGlobalRef |
|
|
465
|
+
ViewRuleAutoLayout
|
|
466
|
+
;
|
|
467
|
+
|
|
468
|
+
ViewRulePredicate:
|
|
469
|
+
(isInclude?='include' | 'exclude')
|
|
470
|
+
exprs=Expressions
|
|
471
|
+
;
|
|
472
|
+
|
|
473
|
+
ViewRuleGlobalPredicateRef:
|
|
474
|
+
'global' 'predicate' predicate=[GlobalPredicateGroup:Id];
|
|
475
|
+
|
|
476
|
+
DynamicViewIncludePredicate:
|
|
477
|
+
'include' exprs=Expressions
|
|
478
|
+
;
|
|
479
|
+
|
|
480
|
+
DynamicViewGlobalPredicateRef:
|
|
481
|
+
'global' 'predicate' predicate=[GlobalDynamicPredicateGroup:Id];
|
|
482
|
+
|
|
483
|
+
|
|
484
|
+
ViewRuleStyle:
|
|
485
|
+
'style' targets=FqnExpressions '{'
|
|
486
|
+
props+=(
|
|
487
|
+
StyleProperty |
|
|
488
|
+
NotationProperty
|
|
489
|
+
)*
|
|
490
|
+
'}';
|
|
491
|
+
|
|
492
|
+
ViewRuleGlobalStyle:
|
|
493
|
+
'global' 'style' style=[GlobalStyleId:Id];
|
|
494
|
+
|
|
495
|
+
ViewRuleStyleOrGlobalRef:
|
|
496
|
+
ViewRuleStyle | ViewRuleGlobalStyle;
|
|
497
|
+
|
|
498
|
+
ViewRuleAutoLayout:
|
|
499
|
+
'autoLayout' direction=ViewLayoutDirection (
|
|
500
|
+
rankSep=Number (
|
|
501
|
+
nodeSep=Number)?
|
|
502
|
+
)? (routing=EdgeRoutingValue)?;
|
|
503
|
+
|
|
504
|
+
NotationProperty:
|
|
505
|
+
key='notation' ':'? value=MarkdownOrString ';'?
|
|
506
|
+
;
|
|
507
|
+
NotesProperty:
|
|
508
|
+
key='notes' ':'? value=MarkdownOrString ';'?
|
|
509
|
+
;
|
|
510
|
+
|
|
511
|
+
CustomElementProperties:
|
|
512
|
+
'{'
|
|
513
|
+
props+=(
|
|
514
|
+
NavigateToProperty |
|
|
515
|
+
ElementStringProperty |
|
|
516
|
+
NotationProperty |
|
|
517
|
+
NotesProperty |
|
|
518
|
+
StyleProperty
|
|
519
|
+
)*
|
|
520
|
+
'}'
|
|
521
|
+
;
|
|
522
|
+
|
|
523
|
+
CustomRelationProperties:
|
|
524
|
+
'{'
|
|
525
|
+
props+=(
|
|
526
|
+
RelationNavigateToProperty |
|
|
527
|
+
RelationStringProperty |
|
|
528
|
+
NotationProperty |
|
|
529
|
+
NotesProperty |
|
|
530
|
+
RelationshipStyleProperty |
|
|
531
|
+
MultipleProperty
|
|
532
|
+
)*
|
|
533
|
+
'}'
|
|
534
|
+
;
|
|
535
|
+
|
|
536
|
+
NavigateToProperty:
|
|
537
|
+
key='navigateTo' value=ViewRef;
|
|
538
|
+
|
|
539
|
+
RelationNavigateToProperty:
|
|
540
|
+
key='navigateTo' value=DynamicViewRef;
|
|
541
|
+
|
|
542
|
+
// Expressions -------------------------------------
|
|
543
|
+
|
|
544
|
+
Expressions:
|
|
545
|
+
value=ExpressionV2 ({infer Expressions.prev=current} ',' (value=ExpressionV2)?)*
|
|
546
|
+
;
|
|
547
|
+
|
|
548
|
+
ExpressionV2:
|
|
549
|
+
RelationExprOrWith |
|
|
550
|
+
FqnExprOrWith
|
|
551
|
+
;
|
|
552
|
+
|
|
553
|
+
FqnExprOrWith:
|
|
554
|
+
FqnExprOrWhere ({infer FqnExprWith.subject=current} 'with' custom=CustomElementProperties?)?
|
|
555
|
+
;
|
|
556
|
+
|
|
557
|
+
FqnExprOrWhere:
|
|
558
|
+
FqnExpr ({infer FqnExprWhere.subject=current} 'where' where=WhereElementExpression?)?
|
|
559
|
+
;
|
|
560
|
+
|
|
561
|
+
RelationExprOrWith:
|
|
562
|
+
RelationExprOrWhere ({infer RelationExprWith.subject=current} 'with' custom=CustomRelationProperties?)?
|
|
563
|
+
;
|
|
564
|
+
|
|
565
|
+
RelationExprOrWhere:
|
|
566
|
+
RelationExpr ({infer RelationExprWhere.subject=current} 'where' where=WhereRelationExpression?)?
|
|
567
|
+
;
|
|
568
|
+
|
|
569
|
+
FqnExpr:
|
|
570
|
+
{infer WildcardExpression} isWildcard?='*' |
|
|
571
|
+
// These are not valid in FqnExpr, but we keep for backward compatibility
|
|
572
|
+
{infer ElementTagExpression} 'element.tag' IsEqual tag=TagRef |
|
|
573
|
+
{infer ElementKindExpression} 'element.kind' IsEqual kind=[ElementKind] |
|
|
574
|
+
FqnRefExpr
|
|
575
|
+
;
|
|
576
|
+
|
|
577
|
+
FqnRefExpr:
|
|
578
|
+
ref=FqnRef selector=(DotUnderscore | DotWildcard)?
|
|
579
|
+
;
|
|
580
|
+
|
|
581
|
+
RelationExpr:
|
|
582
|
+
InOutRelationExpr |
|
|
583
|
+
DirectedRelationExpr
|
|
584
|
+
;
|
|
585
|
+
|
|
586
|
+
InOutRelationExpr infers RelationExpr:
|
|
587
|
+
IncomingRelationExpr ({infer InOutRelationExpr.inout=current} '->')?
|
|
588
|
+
;
|
|
589
|
+
|
|
590
|
+
IncomingRelationExpr:
|
|
591
|
+
'->' to=FqnExpr;
|
|
592
|
+
|
|
593
|
+
DirectedRelationExpr infers RelationExpr:
|
|
594
|
+
OutgoingRelationExpr ({infer DirectedRelationExpr.source=current} target=FqnExpr)?
|
|
595
|
+
;
|
|
596
|
+
|
|
597
|
+
OutgoingRelationExpr:
|
|
598
|
+
from=FqnExpr
|
|
599
|
+
(isBidirectional?='<->' | dotKind=RelationKindDotRef | '->' | '-[' kind=[RelationshipKind:Id] ']->')
|
|
600
|
+
;
|
|
601
|
+
|
|
602
|
+
FqnExpressions:
|
|
603
|
+
value=FqnExpr ({infer FqnExpressions.prev=current} ',' (value=FqnExpr)?)*
|
|
604
|
+
;
|
|
605
|
+
|
|
606
|
+
WhereElementExpression:
|
|
607
|
+
WhereElementOr
|
|
608
|
+
;
|
|
609
|
+
WhereElementOr infers WhereElementExpression:
|
|
610
|
+
WhereElementAnd ({infer WhereBinaryExpression.left=current} operator='or' right=WhereElementAnd)*
|
|
611
|
+
;
|
|
612
|
+
WhereElementAnd infers WhereElementExpression:
|
|
613
|
+
WhereElementPrimary ({infer WhereBinaryExpression.left=current} operator='and' right=WhereElementPrimary)*
|
|
614
|
+
;
|
|
615
|
+
|
|
616
|
+
WhereElementPrimary infers WhereElementExpression:
|
|
617
|
+
'(' WhereElementExpression ')' |
|
|
618
|
+
WhereElementNegation |
|
|
619
|
+
WhereElement
|
|
620
|
+
;
|
|
621
|
+
|
|
622
|
+
WhereElementNegation:
|
|
623
|
+
'not' value=WhereElementExpression;
|
|
624
|
+
|
|
625
|
+
WhereElement:
|
|
626
|
+
{infer WhereElementMetadata} 'metadata' StickyDot key=Id (EqOperator value=MetadataFilterValue)? |
|
|
627
|
+
{infer WhereElementTag} 'tag' EqOperator value=TagRef |
|
|
628
|
+
{infer WhereElementKind} 'kind' EqOperator value=[DeploymentNodeOrElementKind]
|
|
629
|
+
;
|
|
630
|
+
|
|
631
|
+
MetadataFilterValue returns string:
|
|
632
|
+
String | BOOLEAN
|
|
633
|
+
;
|
|
634
|
+
|
|
635
|
+
WhereRelationExpression:
|
|
636
|
+
WhereRelationOr
|
|
637
|
+
;
|
|
638
|
+
|
|
639
|
+
WhereRelationOr infers WhereRelationExpression:
|
|
640
|
+
WhereRelationAnd ({infer WhereBinaryExpression.left=current} operator='or' right=WhereRelationAnd)*
|
|
641
|
+
;
|
|
642
|
+
WhereRelationAnd infers WhereRelationExpression:
|
|
643
|
+
WhereRelationPrimary ({infer WhereBinaryExpression.left=current} operator='and' right=WhereRelationPrimary)*
|
|
644
|
+
;
|
|
645
|
+
|
|
646
|
+
WhereRelationPrimary infers WhereRelationExpression:
|
|
647
|
+
'(' WhereRelationExpression ')' |
|
|
648
|
+
WhereRelationNegation |
|
|
649
|
+
WhereRelation
|
|
650
|
+
;
|
|
651
|
+
|
|
652
|
+
WhereRelationNegation:
|
|
653
|
+
'not' value=WhereRelationExpression;
|
|
654
|
+
|
|
655
|
+
WhereRelation:
|
|
656
|
+
{infer WhereRelationParticipantMetadata} participant=Participant StickyDot 'metadata' StickyDot key=Id (EqOperator value=MetadataFilterValue)? |
|
|
657
|
+
{infer WhereRelationParticipantKind} participant=Participant StickyDot 'kind' EqOperator value=[DeploymentNodeOrElementKind:Id] |
|
|
658
|
+
{infer WhereRelationParticipantTag} participant=Participant StickyDot 'tag' EqOperator value=TagRef |
|
|
659
|
+
{infer WhereRelationMetadata} 'metadata' StickyDot key=Id (EqOperator value=MetadataFilterValue)? |
|
|
660
|
+
{infer WhereRelationKind} 'kind' EqOperator value=[RelationshipKind:Id] |
|
|
661
|
+
{infer WhereRelationTag} 'tag' EqOperator value=TagRef
|
|
662
|
+
;
|
|
663
|
+
type DeploymentNodeOrElementKind = ElementKind | DeploymentNodeKind
|
|
664
|
+
type WhereTagEqual = WhereElementTag | WhereRelationTag | WhereRelationParticipantTag;
|
|
665
|
+
type WhereKindEqual = WhereElementKind | WhereRelationKind | WhereRelationParticipantKind;
|
|
666
|
+
type WhereMetadataEqual = WhereElementMetadata | WhereRelationMetadata | WhereRelationParticipantMetadata;
|
|
667
|
+
|
|
668
|
+
type WhereExpression = WhereElementExpression | WhereRelationExpression;
|
|
669
|
+
|
|
670
|
+
// -----------------------------------------------
|
|
671
|
+
// Dynamic view flow steps
|
|
672
|
+
// -----------------------------------------------
|
|
673
|
+
type StepStatement =
|
|
674
|
+
StepOrSeries |
|
|
675
|
+
TryStep |
|
|
676
|
+
AltSteps |
|
|
677
|
+
SubflowStep;
|
|
678
|
+
|
|
679
|
+
StepStatement returns StepStatement:
|
|
680
|
+
SubflowStep |
|
|
681
|
+
AltSteps |
|
|
682
|
+
TryStep |
|
|
683
|
+
StepSeries
|
|
684
|
+
;
|
|
685
|
+
|
|
686
|
+
interface StepsBlock {
|
|
687
|
+
steps: StepStatement[]
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
fragment StepsBlockFragment:
|
|
691
|
+
'{' steps+=StepStatement* '}'
|
|
692
|
+
;
|
|
693
|
+
|
|
694
|
+
// -----------------------------------------------
|
|
695
|
+
// Semantic group of dynamic view steps (flow branch)
|
|
696
|
+
|
|
697
|
+
type SubflowKind =
|
|
698
|
+
'opt' | 'par' | 'parallel' | 'loop' | 'when' | 'if' | 'else' | 'break';
|
|
699
|
+
SubflowKind returns SubflowKind:
|
|
700
|
+
'opt' | 'par' | 'parallel' | 'loop' | 'when' | 'if' | 'else' | 'break'
|
|
701
|
+
;
|
|
702
|
+
|
|
703
|
+
interface SubflowStep extends StepsBlock {
|
|
704
|
+
kind: SubflowKind
|
|
705
|
+
/// Optional title for the branch
|
|
706
|
+
title?: string
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
// Must be defined before "StepsBlock"
|
|
710
|
+
SubflowStep returns SubflowStep:
|
|
711
|
+
kind=SubflowKind
|
|
712
|
+
title=String? StepsBlockFragment
|
|
713
|
+
;
|
|
714
|
+
|
|
715
|
+
/**
|
|
716
|
+
* Represents a block of step statements, i.e. { ... }
|
|
717
|
+
*/
|
|
718
|
+
StepsBlock returns StepsBlock:
|
|
719
|
+
StepsBlockFragment
|
|
720
|
+
;
|
|
721
|
+
|
|
722
|
+
// -----------------------------------------------
|
|
723
|
+
// Dynamic view TRY block
|
|
724
|
+
|
|
725
|
+
interface TryBlock extends StepsBlock {
|
|
726
|
+
/// Optional title for the try block
|
|
727
|
+
title?: string
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
interface CatchBlock {
|
|
731
|
+
try: TryBlock
|
|
732
|
+
// Optional title for the catch block
|
|
733
|
+
title?: string
|
|
734
|
+
catch: StepsBlock
|
|
735
|
+
}
|
|
736
|
+
|
|
737
|
+
interface FinallyBlock {
|
|
738
|
+
tryCatch: TryBlock | CatchBlock
|
|
739
|
+
// Optional title for the finally block
|
|
740
|
+
title?: string
|
|
741
|
+
finally: StepsBlock
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
type TryStep =
|
|
745
|
+
TryBlock |
|
|
746
|
+
CatchBlock |
|
|
747
|
+
FinallyBlock;
|
|
748
|
+
|
|
749
|
+
TryStep returns TryStep:
|
|
750
|
+
FinallyBlock;
|
|
751
|
+
|
|
752
|
+
FinallyBlock returns FinallyBlock:
|
|
753
|
+
CatchBlock ({FinallyBlock.tryCatch=current}
|
|
754
|
+
'finally' title=String?
|
|
755
|
+
finally=StepsBlock
|
|
756
|
+
)?
|
|
757
|
+
;
|
|
758
|
+
|
|
759
|
+
CatchBlock returns CatchBlock:
|
|
760
|
+
TryBlock ({CatchBlock.try=current}
|
|
761
|
+
'catch' title=String?
|
|
762
|
+
catch=StepsBlock
|
|
763
|
+
)?
|
|
764
|
+
;
|
|
765
|
+
|
|
766
|
+
TryBlock returns TryBlock:
|
|
767
|
+
'try' title=String? StepsBlockFragment
|
|
768
|
+
;
|
|
769
|
+
|
|
770
|
+
// -----------------------------------------------
|
|
771
|
+
// Dynamic view ALT block
|
|
772
|
+
|
|
773
|
+
interface AltSteps {
|
|
774
|
+
title?: string
|
|
775
|
+
branches: SubflowStep[]
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
AltSteps returns AltSteps:
|
|
779
|
+
'alt' title=String? '{' branches+=SubflowStep* '}'
|
|
780
|
+
;
|
|
781
|
+
|
|
782
|
+
|
|
783
|
+
// -----------------------------------------------
|
|
784
|
+
// Dynamic view step (from previous model)
|
|
785
|
+
|
|
786
|
+
fragment StepTarget:
|
|
787
|
+
target=ElementRef
|
|
788
|
+
title=String?
|
|
789
|
+
custom=CustomRelationProperties?
|
|
790
|
+
;
|
|
791
|
+
|
|
792
|
+
interface AbstractStep {
|
|
793
|
+
kind?: @RelationshipKind;
|
|
794
|
+
dotKind?: RelationKindDotRef;
|
|
795
|
+
target: ElementRef;
|
|
796
|
+
title?: string;
|
|
797
|
+
custom?: CustomRelationProperties;
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
/**
|
|
801
|
+
* A single step in a dynamic view flow
|
|
802
|
+
* source -> target
|
|
803
|
+
*/
|
|
804
|
+
interface Step extends AbstractStep {
|
|
805
|
+
source: ElementRef;
|
|
806
|
+
isBackward?: boolean;
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
/**
|
|
810
|
+
* A series of steps in a dynamic view flow
|
|
811
|
+
* source -> target1 -> target2 -> ...
|
|
812
|
+
*/
|
|
813
|
+
interface StepSeries extends AbstractStep {
|
|
814
|
+
source: Step | StepSeries;
|
|
815
|
+
}
|
|
816
|
+
|
|
817
|
+
type StepOrSeries = Step | StepSeries;
|
|
818
|
+
|
|
819
|
+
StepSeries returns StepSeries:
|
|
820
|
+
Step
|
|
821
|
+
({StepSeries.source=current}
|
|
822
|
+
(dotKind=RelationKindDotRef | '->' | '-[' kind=[RelationshipKind] ']->')
|
|
823
|
+
StepTarget
|
|
824
|
+
)*
|
|
825
|
+
;
|
|
826
|
+
|
|
827
|
+
Step returns Step:
|
|
828
|
+
source=ElementRef
|
|
829
|
+
(isBackward?='<-' | dotKind=RelationKindDotRef | '->' | '-[' kind=[RelationshipKind] ']->')
|
|
830
|
+
StepTarget
|
|
831
|
+
;
|
|
832
|
+
|
|
833
|
+
// Deployment -------------------------------------
|
|
834
|
+
|
|
835
|
+
ModelDeployments:
|
|
836
|
+
name='deployment' '{'
|
|
837
|
+
elements+=(
|
|
838
|
+
DeploymentNode |
|
|
839
|
+
DeploymentRelation<true> |
|
|
840
|
+
ExtendDeployment
|
|
841
|
+
)*
|
|
842
|
+
'}';
|
|
843
|
+
|
|
844
|
+
type DeploymentElement = DeploymentNode | DeployedInstance;
|
|
845
|
+
|
|
846
|
+
DeploymentNode:
|
|
847
|
+
(
|
|
848
|
+
kind=[DeploymentNodeKind:Id] name=Id |
|
|
849
|
+
name=Id Eq kind=[DeploymentNodeKind:Id]
|
|
850
|
+
)
|
|
851
|
+
(
|
|
852
|
+
title=String
|
|
853
|
+
summary=String?
|
|
854
|
+
)?
|
|
855
|
+
body=DeploymentNodeBody?
|
|
856
|
+
;
|
|
857
|
+
|
|
858
|
+
DeploymentNodeBody:
|
|
859
|
+
'{'
|
|
860
|
+
tags=Tags?
|
|
861
|
+
props+=ElementProperty*
|
|
862
|
+
elements+=(
|
|
863
|
+
DeployedInstance |
|
|
864
|
+
DeploymentRelation<false> |
|
|
865
|
+
DeploymentNode
|
|
866
|
+
)*
|
|
867
|
+
'}';
|
|
868
|
+
|
|
869
|
+
DeployedInstance:
|
|
870
|
+
(name=Id Eq)?
|
|
871
|
+
'instanceOf'
|
|
872
|
+
target=ElementRef
|
|
873
|
+
(
|
|
874
|
+
title=String
|
|
875
|
+
summary=String?
|
|
876
|
+
)?
|
|
877
|
+
body=DeployedInstanceBody?
|
|
878
|
+
';'?
|
|
879
|
+
;
|
|
880
|
+
|
|
881
|
+
DeployedInstanceBody:
|
|
882
|
+
'{'
|
|
883
|
+
tags=Tags?
|
|
884
|
+
props+=ElementProperty*
|
|
885
|
+
elements+=(
|
|
886
|
+
DeploymentRelation<false>
|
|
887
|
+
)*
|
|
888
|
+
'}';
|
|
889
|
+
|
|
890
|
+
ExtendDeployment:
|
|
891
|
+
'extend' deploymentNode=StrictFqnRef body=ExtendDeploymentBody
|
|
892
|
+
;
|
|
893
|
+
|
|
894
|
+
ExtendDeploymentBody:
|
|
895
|
+
'{'
|
|
896
|
+
tags=Tags?
|
|
897
|
+
props+=ExtendElementProperty*
|
|
898
|
+
|
|
899
|
+
elements+=(
|
|
900
|
+
DeployedInstance |
|
|
901
|
+
DeploymentRelation<true> |
|
|
902
|
+
DeploymentNode
|
|
903
|
+
)*
|
|
904
|
+
'}'
|
|
905
|
+
;
|
|
906
|
+
|
|
907
|
+
|
|
908
|
+
DeploymentRelation<isExplicit>:
|
|
909
|
+
(<isExplicit> source=FqnRef | <!isExplicit> source=FqnRef?)
|
|
910
|
+
RelationConnector
|
|
911
|
+
target=FqnRef
|
|
912
|
+
(title=String // title
|
|
913
|
+
(description=String // description
|
|
914
|
+
(technology=String)?
|
|
915
|
+
)?
|
|
916
|
+
)?
|
|
917
|
+
tags=Tags?
|
|
918
|
+
body=DeploymentRelationBody?
|
|
919
|
+
;
|
|
920
|
+
|
|
921
|
+
DeploymentRelationBody:
|
|
922
|
+
'{'
|
|
923
|
+
tags=Tags?
|
|
924
|
+
props+=RelationProperty*
|
|
925
|
+
'}'
|
|
926
|
+
;
|
|
927
|
+
|
|
928
|
+
DeploymentView:
|
|
929
|
+
'deployment' 'view' name=Id body=DeploymentViewBody?
|
|
930
|
+
;
|
|
931
|
+
|
|
932
|
+
DeploymentViewBody:
|
|
933
|
+
'{'
|
|
934
|
+
tags=Tags?
|
|
935
|
+
props+=ViewProperty*
|
|
936
|
+
rules+=DeploymentViewRule*
|
|
937
|
+
'}';
|
|
938
|
+
|
|
939
|
+
DeploymentViewRule:
|
|
940
|
+
DeploymentViewRulePredicate |
|
|
941
|
+
DeploymentViewRuleGroup |
|
|
942
|
+
DeploymentViewRuleStyle |
|
|
943
|
+
ViewRuleAutoLayout |
|
|
944
|
+
ViewRuleAncestors
|
|
945
|
+
;
|
|
946
|
+
|
|
947
|
+
DeploymentViewRuleGroup:
|
|
948
|
+
'group' title=String? '{'
|
|
949
|
+
props+=(
|
|
950
|
+
ColorProperty |
|
|
951
|
+
BorderProperty |
|
|
952
|
+
OpacityProperty |
|
|
953
|
+
MultipleProperty |
|
|
954
|
+
ShapeSizeProperty |
|
|
955
|
+
PaddingSizeProperty |
|
|
956
|
+
TextSizeProperty
|
|
957
|
+
)*
|
|
958
|
+
groupRules+=(
|
|
959
|
+
DeploymentViewRulePredicate |
|
|
960
|
+
DeploymentViewRuleGroup
|
|
961
|
+
)*
|
|
962
|
+
'}';
|
|
963
|
+
|
|
964
|
+
ViewRuleAncestors:
|
|
965
|
+
key='includeAncestors' ':'? value=BOOLEAN ';'?
|
|
966
|
+
;
|
|
967
|
+
|
|
968
|
+
DeploymentViewRuleStyle:
|
|
969
|
+
'style' targets=FqnExpressions '{'
|
|
970
|
+
props+=(
|
|
971
|
+
StyleProperty |
|
|
972
|
+
NotationProperty
|
|
973
|
+
)*
|
|
974
|
+
'}';
|
|
975
|
+
|
|
976
|
+
|
|
977
|
+
DeploymentViewRulePredicate:
|
|
978
|
+
(isInclude?='include' | 'exclude')
|
|
979
|
+
expr=Expressions
|
|
980
|
+
;
|
|
981
|
+
// Model diff -------------------------------------
|
|
982
|
+
// Named change set of the model: elements and relations to remove, and model elements to add
|
|
983
|
+
|
|
984
|
+
ModelDiff:
|
|
985
|
+
'diff' name=Id title=String? '{'
|
|
986
|
+
(
|
|
987
|
+
props+=DiffStringProperty |
|
|
988
|
+
removes+=DiffRemove |
|
|
989
|
+
adds+=DiffAdd
|
|
990
|
+
)*
|
|
991
|
+
'}'
|
|
992
|
+
;
|
|
993
|
+
|
|
994
|
+
DiffStringProperty:
|
|
995
|
+
key=('title' | 'description') ':'? value=MarkdownOrString ';'?;
|
|
996
|
+
|
|
997
|
+
DiffRemove:
|
|
998
|
+
'remove' '{'
|
|
999
|
+
entries+=DiffRemoveEntry*
|
|
1000
|
+
'}'
|
|
1001
|
+
;
|
|
1002
|
+
|
|
1003
|
+
// Element (source only) or relation (source, connector and target)
|
|
1004
|
+
DiffRemoveEntry:
|
|
1005
|
+
source=FqnRef
|
|
1006
|
+
(
|
|
1007
|
+
RelationConnector
|
|
1008
|
+
target=FqnRef
|
|
1009
|
+
title=String?
|
|
1010
|
+
)?
|
|
1011
|
+
';'?
|
|
1012
|
+
;
|
|
1013
|
+
|
|
1014
|
+
DiffAdd:
|
|
1015
|
+
'add' '{'
|
|
1016
|
+
elements+=ModelElement*
|
|
1017
|
+
'}'
|
|
1018
|
+
;
|
|
1019
|
+
|
|
1020
|
+
// Global -------------------------------------
|
|
1021
|
+
|
|
1022
|
+
Globals:
|
|
1023
|
+
name='global' '{'
|
|
1024
|
+
(
|
|
1025
|
+
predicates+=(GlobalPredicateGroup | GlobalDynamicPredicateGroup) |
|
|
1026
|
+
styles+=(GlobalStyle | GlobalStyleGroup)
|
|
1027
|
+
)*
|
|
1028
|
+
'}';
|
|
1029
|
+
|
|
1030
|
+
GlobalPredicateGroup:
|
|
1031
|
+
'predicateGroup' name=Id '{'
|
|
1032
|
+
predicates+=ViewRulePredicate*
|
|
1033
|
+
'}';
|
|
1034
|
+
|
|
1035
|
+
GlobalDynamicPredicateGroup:
|
|
1036
|
+
'dynamicPredicateGroup' name=Id '{'
|
|
1037
|
+
predicates+=DynamicViewIncludePredicate*
|
|
1038
|
+
'}';
|
|
1039
|
+
|
|
1040
|
+
GlobalStyleId:
|
|
1041
|
+
name=Id;
|
|
1042
|
+
|
|
1043
|
+
GlobalStyle:
|
|
1044
|
+
'style' id=GlobalStyleId targets=FqnExpressions '{'
|
|
1045
|
+
props+=(
|
|
1046
|
+
StyleProperty |
|
|
1047
|
+
NotationProperty
|
|
1048
|
+
)*
|
|
1049
|
+
'}';
|
|
1050
|
+
|
|
1051
|
+
GlobalStyleGroup:
|
|
1052
|
+
'styleGroup' id=GlobalStyleId '{'
|
|
1053
|
+
styles+=ViewRuleStyle*
|
|
1054
|
+
'}';
|
|
1055
|
+
|
|
1056
|
+
type FqnReferenceable = Referenceable | Element | ExtendElement | ExtendDeployment;
|
|
1057
|
+
|
|
1058
|
+
// Common properties -------------------------------------
|
|
1059
|
+
|
|
1060
|
+
LinkProperty:
|
|
1061
|
+
key='link' ':'? value=Uri title=String? ';'?;
|
|
1062
|
+
|
|
1063
|
+
// A path to a markdown file, resolved like a link and read when the model is built
|
|
1064
|
+
DescriptionFileProperty:
|
|
1065
|
+
key='descriptionFile' ':'? value=Uri ';'?;
|
|
1066
|
+
|
|
1067
|
+
fragment ColorRef:
|
|
1068
|
+
themeColor=ThemeColor | customColor=[CustomColor:CustomColorId];
|
|
1069
|
+
|
|
1070
|
+
ColorProperty:
|
|
1071
|
+
key='color' ':'? ColorRef ';'?;
|
|
1072
|
+
|
|
1073
|
+
OpacityProperty:
|
|
1074
|
+
key='opacity' ':'? value=Percent ';'?;
|
|
1075
|
+
|
|
1076
|
+
MultipleProperty:
|
|
1077
|
+
key='multiple' ':'? value=BOOLEAN ';'?;
|
|
1078
|
+
|
|
1079
|
+
// Element properties -------------------------------------
|
|
1080
|
+
IconProperty:
|
|
1081
|
+
key='icon' ':'? (libicon=[LibIcon:IconId] | value=('none'|Uri)) ';'?;
|
|
1082
|
+
|
|
1083
|
+
IconColorProperty:
|
|
1084
|
+
key='iconColor' ':'? ColorRef ';'?;
|
|
1085
|
+
|
|
1086
|
+
IconSizeProperty:
|
|
1087
|
+
key='iconSize' ':'? value=SizeValue ';'?;
|
|
1088
|
+
|
|
1089
|
+
IconPositionValue returns string:
|
|
1090
|
+
'left' |
|
|
1091
|
+
'right' |
|
|
1092
|
+
'top' |
|
|
1093
|
+
'bottom';
|
|
1094
|
+
|
|
1095
|
+
IconPositionProperty:
|
|
1096
|
+
key='iconPosition' ':'? value=IconPositionValue ';'?;
|
|
1097
|
+
|
|
1098
|
+
ShapeProperty:
|
|
1099
|
+
key='shape' ':'? value=ElementShape ';'?;
|
|
1100
|
+
|
|
1101
|
+
BorderStyleValue returns string:
|
|
1102
|
+
LineOptions | 'none';
|
|
1103
|
+
|
|
1104
|
+
BorderProperty:
|
|
1105
|
+
key='border' ':'? value=BorderStyleValue ';'?;
|
|
1106
|
+
|
|
1107
|
+
SizeValue returns string:
|
|
1108
|
+
'xs' |
|
|
1109
|
+
'sm' |
|
|
1110
|
+
'md' |
|
|
1111
|
+
'lg' |
|
|
1112
|
+
'xl' |
|
|
1113
|
+
'xsmall' |
|
|
1114
|
+
'small' |
|
|
1115
|
+
'medium' |
|
|
1116
|
+
'large' |
|
|
1117
|
+
'xlarge';
|
|
1118
|
+
|
|
1119
|
+
ShapeSizeProperty:
|
|
1120
|
+
key='size' ':'? value=SizeValue ';'?;
|
|
1121
|
+
|
|
1122
|
+
PaddingSizeProperty:
|
|
1123
|
+
key='padding' ':'? value=SizeValue ';'?;
|
|
1124
|
+
|
|
1125
|
+
TextSizeProperty:
|
|
1126
|
+
key='textSize' ':'? value=SizeValue ';'?;
|
|
1127
|
+
|
|
1128
|
+
SizingValue returns string:
|
|
1129
|
+
'auto' |
|
|
1130
|
+
'fixed';
|
|
1131
|
+
|
|
1132
|
+
SizingProperty:
|
|
1133
|
+
key='sizing' ':'? value=SizingValue ';'?;
|
|
1134
|
+
|
|
1135
|
+
type SizeProperty = ShapeSizeProperty | PaddingSizeProperty | TextSizeProperty | IconSizeProperty;
|
|
1136
|
+
|
|
1137
|
+
StyleProperty:
|
|
1138
|
+
ColorProperty |
|
|
1139
|
+
ShapeProperty |
|
|
1140
|
+
BorderProperty |
|
|
1141
|
+
OpacityProperty |
|
|
1142
|
+
IconProperty |
|
|
1143
|
+
IconColorProperty |
|
|
1144
|
+
MultipleProperty |
|
|
1145
|
+
ShapeSizeProperty |
|
|
1146
|
+
PaddingSizeProperty |
|
|
1147
|
+
TextSizeProperty |
|
|
1148
|
+
IconSizeProperty |
|
|
1149
|
+
IconPositionProperty |
|
|
1150
|
+
SizingProperty
|
|
1151
|
+
;
|
|
1152
|
+
|
|
1153
|
+
ElementStyleProperty:
|
|
1154
|
+
key='style' '{'
|
|
1155
|
+
props+=StyleProperty*
|
|
1156
|
+
'}';
|
|
1157
|
+
|
|
1158
|
+
|
|
1159
|
+
// -------------------------
|
|
1160
|
+
// Relationship Style Properties
|
|
1161
|
+
LineProperty:
|
|
1162
|
+
key='line' ':'? value=LineOptions ';'?;
|
|
1163
|
+
ArrowProperty:
|
|
1164
|
+
key=('head' | 'tail') ':'? value=ArrowType ';'?;
|
|
1165
|
+
|
|
1166
|
+
RelationshipStyleProperty:
|
|
1167
|
+
ColorProperty | LineProperty | ArrowProperty;
|
|
1168
|
+
|
|
1169
|
+
TagRef:
|
|
1170
|
+
tag=[Tag:HashId]
|
|
1171
|
+
;
|
|
1172
|
+
|
|
1173
|
+
RelationKindDotRef:
|
|
1174
|
+
Dot kind=[RelationshipKind:Id]
|
|
1175
|
+
;
|
|
1176
|
+
|
|
1177
|
+
LineOptions returns string:
|
|
1178
|
+
'solid' |
|
|
1179
|
+
'dashed' |
|
|
1180
|
+
'dotted'
|
|
1181
|
+
;
|
|
1182
|
+
|
|
1183
|
+
ArrowType returns string:
|
|
1184
|
+
'none' |
|
|
1185
|
+
'normal' |
|
|
1186
|
+
'onormal' |
|
|
1187
|
+
'dot' |
|
|
1188
|
+
'odot' |
|
|
1189
|
+
'diamond' |
|
|
1190
|
+
'odiamond' |
|
|
1191
|
+
'crow' |
|
|
1192
|
+
'open' |
|
|
1193
|
+
'vee'
|
|
1194
|
+
;
|
|
1195
|
+
|
|
1196
|
+
DynamicViewDisplayVariantValue returns string:
|
|
1197
|
+
'diagram' | 'sequence';
|
|
1198
|
+
|
|
1199
|
+
DynamicViewFlowKeyword returns string:
|
|
1200
|
+
'alt' |
|
|
1201
|
+
'opt' |
|
|
1202
|
+
'par' |
|
|
1203
|
+
'parallel' |
|
|
1204
|
+
'loop' |
|
|
1205
|
+
'when' |
|
|
1206
|
+
'if' |
|
|
1207
|
+
'else' |
|
|
1208
|
+
'break' |
|
|
1209
|
+
'try' |
|
|
1210
|
+
'catch' |
|
|
1211
|
+
'finally';
|
|
1212
|
+
|
|
1213
|
+
ThemeColor returns string:
|
|
1214
|
+
'primary' |
|
|
1215
|
+
'secondary' |
|
|
1216
|
+
'muted' |
|
|
1217
|
+
'slate' |
|
|
1218
|
+
'blue' |
|
|
1219
|
+
'indigo' |
|
|
1220
|
+
'sky' |
|
|
1221
|
+
'red' |
|
|
1222
|
+
'gray' |
|
|
1223
|
+
'green' |
|
|
1224
|
+
'amber';
|
|
1225
|
+
|
|
1226
|
+
ElementShape returns string:
|
|
1227
|
+
'rectangle' |
|
|
1228
|
+
'component' |
|
|
1229
|
+
'person' |
|
|
1230
|
+
'browser' |
|
|
1231
|
+
'mobile' |
|
|
1232
|
+
'cylinder' |
|
|
1233
|
+
'storage' |
|
|
1234
|
+
'queue' |
|
|
1235
|
+
'bucket' |
|
|
1236
|
+
'document' |
|
|
1237
|
+
'agent';
|
|
1238
|
+
|
|
1239
|
+
Participant returns string:
|
|
1240
|
+
'source' | 'target';
|
|
1241
|
+
|
|
1242
|
+
ColorLiteral:
|
|
1243
|
+
RGBAColor | HexColor;
|
|
1244
|
+
|
|
1245
|
+
RGBAColor:
|
|
1246
|
+
('rgba' | 'rgb') '(' red=Number ','? green=Number ','? blue=Number ','? alpha=(Float | Number | Percent)? ')';
|
|
1247
|
+
|
|
1248
|
+
// Validated later
|
|
1249
|
+
HexColor:
|
|
1250
|
+
Hash hex=(Hex | Number | IdTerminal | 'add');
|
|
1251
|
+
|
|
1252
|
+
IconId returns string:
|
|
1253
|
+
LIB_ICON;
|
|
1254
|
+
|
|
1255
|
+
Uri returns string:
|
|
1256
|
+
URI_WITH_SCHEMA | URI_RELATIVE | URI_ALIAS;
|
|
1257
|
+
|
|
1258
|
+
MarkdownOrString:
|
|
1259
|
+
markdown=MarkdownString | text=String;
|
|
1260
|
+
|
|
1261
|
+
CustomColorId returns string:
|
|
1262
|
+
IdTerminal |
|
|
1263
|
+
SizingValue |
|
|
1264
|
+
ElementShape |
|
|
1265
|
+
ArrowType |
|
|
1266
|
+
LineOptions |
|
|
1267
|
+
Participant |
|
|
1268
|
+
'element' |
|
|
1269
|
+
'model' |
|
|
1270
|
+
'diff' |
|
|
1271
|
+
'add' |
|
|
1272
|
+
'remove';
|
|
1273
|
+
|
|
1274
|
+
// We need to add all the possible terminal values to Id,
|
|
1275
|
+
// so that the parser can accept them as "Id" (not a bug and not a feature of Langium)
|
|
1276
|
+
Id returns string:
|
|
1277
|
+
IdTerminal |
|
|
1278
|
+
ElementShape |
|
|
1279
|
+
ThemeColor |
|
|
1280
|
+
ArrowType |
|
|
1281
|
+
LineOptions |
|
|
1282
|
+
Participant |
|
|
1283
|
+
SizeValue |
|
|
1284
|
+
DynamicViewDisplayVariantValue |
|
|
1285
|
+
DynamicViewFlowKeyword |
|
|
1286
|
+
IconPositionValue |
|
|
1287
|
+
SizingValue |
|
|
1288
|
+
RankValue |
|
|
1289
|
+
EdgeRoutingValue |
|
|
1290
|
+
// Allow reserved keywords as Id
|
|
1291
|
+
'element' | 'model' | 'group' | 'node' | 'deployment' | 'instance' | 'relationship' | 'diff' | 'add' | 'remove' | 'routing';
|
|
1292
|
+
|
|
1293
|
+
HashId returns string:
|
|
1294
|
+
Hash Id;
|
|
1295
|
+
|
|
1296
|
+
fragment EqOperator:
|
|
1297
|
+
(
|
|
1298
|
+
operator=(Eq | NotEqual) |
|
|
1299
|
+
operator="is" not?='not'?
|
|
1300
|
+
)
|
|
1301
|
+
;
|
|
1302
|
+
|
|
1303
|
+
fragment IsEqual:
|
|
1304
|
+
isEqual?=Eq | NotEqual;
|
|
1305
|
+
|
|
1306
|
+
// -----------------------------------
|
|
1307
|
+
// Symbols
|
|
1308
|
+
// terminal fragment HASH: '#';
|
|
1309
|
+
// terminal fragment UNDERSCORE: '_';
|
|
1310
|
+
// terminal fragment DASH: '-';
|
|
1311
|
+
// terminal fragment LETTER: /[^\W\d_]/;
|
|
1312
|
+
// terminal fragment DIGIT: /[0-9]/;
|
|
1313
|
+
// terminal fragment NEWLINE: /[\r?\n]/;
|
|
1314
|
+
// terminal fragment SPACE: /[^\S\r\n]/;
|
|
1315
|
+
|
|
1316
|
+
// -------------------------
|
|
1317
|
+
// Comments
|
|
1318
|
+
hidden terminal BLOCK_COMMENT: /\/\*[\s\S]*?\*\//;
|
|
1319
|
+
hidden terminal LINE_COMMENT: /\/\/[^\n\r]*/;
|
|
1320
|
+
hidden terminal WS: /[\t ]+/;
|
|
1321
|
+
hidden terminal NL: /[\r\n]+/;
|
|
1322
|
+
|
|
1323
|
+
// -----------------------------------
|
|
1324
|
+
// Terminals
|
|
1325
|
+
//terminal LineStartWithDash: /(?<=([\r?\n][^\S\r\n]*))-/;
|
|
1326
|
+
// terminal Boolean returns boolean: 'true' | 'false';
|
|
1327
|
+
|
|
1328
|
+
terminal BOOLEAN returns boolean: /\b(true|false)\b/;
|
|
1329
|
+
// LibIcons
|
|
1330
|
+
terminal LIB_ICON: /(aws|azure|bootstrap|gcp|md|tech):[-\w]*/;
|
|
1331
|
+
|
|
1332
|
+
terminal URI_WITH_SCHEMA: /\w+:\/{2}\S+/;
|
|
1333
|
+
terminal URI_RELATIVE: /\.{0,2}\/[^\/]\S+/;
|
|
1334
|
+
terminal URI_ALIAS: /@[a-zA-Z0-9_-]*\/[^\s]+/;
|
|
1335
|
+
|
|
1336
|
+
terminal DotUnderscore: /\b\._(?![_a-zA-Z])/;
|
|
1337
|
+
terminal DotWildcard: /\b\.\*{1,2}/;
|
|
1338
|
+
// terminal HashPrefix: /\B#\b/;
|
|
1339
|
+
terminal Hash: '#';
|
|
1340
|
+
|
|
1341
|
+
// No space allowed before dot
|
|
1342
|
+
terminal StickyDot: /\b\./;
|
|
1343
|
+
terminal Dot: '.';
|
|
1344
|
+
terminal NotEqual: /\!\={1,2}/;
|
|
1345
|
+
terminal Eq: /\={1,2}/;
|
|
1346
|
+
terminal Percent: /\b\d+%/;
|
|
1347
|
+
|
|
1348
|
+
terminal MarkdownString: '\'\'\'' -> '\'\'\'' | '"""' -> '"""';
|
|
1349
|
+
terminal String: /"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*'/;
|
|
1350
|
+
|
|
1351
|
+
// terminal fragment QuotedString: ;
|
|
1352
|
+
|
|
1353
|
+
// terminal TagId: HASH LETTER (LETTER | DIGIT | UNDERSCORE | DASH)*;
|
|
1354
|
+
terminal Float returns number: /\b\d+\.\d+\b/;
|
|
1355
|
+
terminal Number returns number: /\b\d+\b/;
|
|
1356
|
+
terminal IdTerminal: /([a-zA-Z]|_+[a-zA-Z0-9])[-\w]*/;
|
|
1357
|
+
terminal Hex: /[a-fA-F0-9]{3,}(?![-_g-zG-Z])/;
|