1 = Java Binding Specification 2
2 Tony Tkacik <ttkacik@cisco.com>; Robert Varga <rovarga@cisco.com>; Martin Sunal <msunal@cisco.com>; Martin Ciglan <mciglan@cisco.com>
3 :rfc6020: https://tools.ietf.org/html/rfc6020
12 naming space, in which all identifiers needs to be unique
17 Instantiated Data Node::
18 Instantiated Data Tree::
23 === YANG Identifiers Mapping
25 Every non-Java char in identifier is converted to Java char by its unicode name http://docs.oracle.com/javase/specs/jls/se8/html/jls-3.html#jls-3.8
26 JAVA SE SPECIFICATIONS - Identifiers. This mapping solves various issues from Binding Specification v1, which led to compilation issues.
28 There are special types of mapping non-java chars to original identifiers according to specific Java type:
30 * class, enum, interface
32 ** without special separator
33 the first character of identifier, any other first character of identifier part mapped by
34 ** non-Java char name from unicode and char in identifier behind non-java char name are converting to upper case
37 example* - ExampleAsterisk
38 example*example - ExampleAserisksExample
39 \example - ReverseSolidusExample
40 1example - DigitOneExample
42 int - IntReservedKeyword
43 con - ConReservedKeyword
45 * enum value, constant
46 ** used underscore as special separator
47 ** converted identifier to upper case
50 example* - EXAMPLE_ASTERISK
51 example*example - EXAMPLE_ASTERISK_EXAMPLE
52 \example - REVERSE_SOLIDUS_EXAMPLE
53 1example - DIGIT_ONE_EXAMPLE
55 int - INT_RESERVED_KEYWORD
56 con - CON_RESERVED_KEYWORD
59 ** without special separator
60 ** the first character of identifier is converting to lower case
61 ** any other first character of identifier part mapped by non-Java char name from unicode and char in identifier behind non-java char name are converting to upper case
64 example* - exampleAsterisk
65 example*example - exampleAserisksExample
66 \example - reverseSolidusExample
67 1example - digitOneExample
69 int - intReservedKeyword
70 con - conReservedKeyword
72 * package - full package name - https://docs.oracle.com/javase/tutorial/java/package/namingpkgs.html
73 ** parts of package name are separated by dots
74 ** parts of package name are converting to lower case
75 ** if parts of package name are reserved Java or Windows keywords, such as 'int' the suggested convention is to add an underscore to keyword
76 ** dash is parsed as underscore according to https://docs.oracle.com/javase/tutorial/java/package/namingpkgs.html
79 org.example* - org.exampleasterisk
80 org.example*example - org.exampleasteriskexample
81 org.example - org.reversesolidusexample
82 org.1example - org.digitoneexample
83 org.example1 - org.example1
86 org.foo-cont - org.foo_cont
88 ==== Special case - '-' in identifiers
89 There is special case in CLASS, INTERFACE, ENUM, ENUM VALUE, CONSTANT, METHOD and VARIABLE if
90 identifier contains single dash - then the converter ignores the single dash in the way of the
91 non-java chars. In other way, if dash is the first or the last char in the identifier or there is
92 more dashes in a row in the identifier, then these dashes are converted as non-java chars.
96 * class, enum, interface
99 foo--cont - FooHyphenMinusHyphenMinusCont
100 -foo - HyphenMinusFoo
101 foo- - FooHyphenMinus
103 * enum value, constant
106 foo--cont - FOO_HYPHEN_MINUS_HYPHEN_MINUS_CONT
107 -foo - HYPHEN_MINUS_FOO
108 foo- - FOO_HYPHEN_MINUS
113 foo--cont - fooHyphenMinusHyphenMinusCont
114 -foo - hyphenMinusFoo
115 foo- - fooHyphenMinus
117 ==== Special case - same class (or enum or interface) names with different camel cases
118 Next special case talks about normalizing class name which already exists in package - but with
119 different camel cases (foo, Foo, fOo, ...). To every next classes with same names will by added
120 their actual rank (serial number), except the first one. This working for CLASS, ENUM and
121 INTEFACE java identifiers. If there exist the same ENUM VALUES in ENUM (with different camel
122 cases), then it's parsed with same logic like CLASSES, ENUMS and INTERFACES but according to list
123 of pairs of their ENUM parent. Example:
125 * class, enum, interface
127 package name org.example, class (or interface or enum) Foo - normalized to Foo
128 package name org.example, class (or interface or enum) fOo - normalized to Foo1
136 YANG enum values will be mapped to 'FOO' and 'FOO_1' Java enum values.
139 === Binding Specification v2 Concepts
142 Represent node, which is instantiable by users as a part of notification,
143 rpc, action or data tree.
145 Represents node, which is part of instantiated data tree, this interface
146 is not used directly, but rather via <<TreeChildNode>>. See <<instantiated-data-tree-rules>>
147 for more information.
149 Represents virtual root of instantiated data tree.
151 Represents node, which is part of instantiated data tree and is not root of
154 Represents instantiated node, which is subjectible to be extended / augmented
155 by `augment` statement from external module.
157 Represents extension to instantiated node, which is introduced from different
158 model than instantiated node.
159 <<InstanceIdentifier>>::
160 Unique identifier of node / subtree in data tree, which provides unambiguous
161 information, how to reference node / subtree in Instantiated Data Tree.
166 .2+|Statement .2+| In groupings 3+| Instantiable .2+| Augmentable
167 | In Data | In RPC | In Notification
169 | `grouping` | Yes | No | No | No | No
171 | `container` | Yes | Yes | Yes | Yes | Yes
173 | `leaf` | Yes | Yes | Yes | Yes | No
175 | `leaf-list` | Yes | Yes | Yes | Yes | No
177 | `list` | Yes | Yes | Yes | Yes | Yes
179 | `anydata` | Yes | Yes | Yes | Yes | No
181 | `anyxml` | Yes | Yes | Yes | Yes | No
183 | `choice` | Yes | Yes | Yes | Yes | Yes
185 | `case` | Yes | Yes | Yes | Yes | Yes
187 | `input` | Yes | No | Yes | No | Yes
189 | `output` | Yes | No | Yes | No | Yes
191 | `notification` | Yes | No | No | Yes | Yes
197 YANG defines several namespaces and naming space of YANG is wider then applicable
198 namespace of JAVA language. In order to decrease conflicts between various
199 YANG-defined namespaces and classes introduced by Binding Specification, it
202 * separate namespaces by Java package hierarchy
203 ** each namespace must define rules how to construct package name, which
204 will not conflict with other namespace
205 * if multiple classes are generated for YANG statement they need to be in separate
206 packages to decrease possible conflicts with siblings.
207 * if Binding Specification introduces new concepts, which does not have explicit
208 namespace rules in YANG, these concepts needs to be in their own, separate
209 namespaces, in order to not conflict on valid YANG namespace items.
212 This rules allows to identify two types of namespaces:
214 .Namespace types by source of namespace
216 Naming space explicitly defined in YANG specification, which needs to be
217 explicitly supported in order to prevent naming conflicts.
219 Naming space introduced by Binding Specification for additional properties
220 and functionality of Binding Specification. This namespaces needs to be separate
221 from YANG namespaces in order to not have naming conflict with YANG-derived.
224 Binding Specification v2 uses following namespaces:
226 .Concrete namespaces used in Binding Specification
227 <<module-namespace>>::
228 YANG namespace containing representation for all modules.
229 <<identity-namespace>>::
230 YANG namespace containing representation for all `identity` statements. Identities
231 needs to be separated to prevent naming conflict between Grouping, Data, Type
234 YANG namespace containing representation for all `typedef` statements and
235 annonymous definitions of `union`, `enumeration` and `bits` types. Types needs
236 to be seperated to prevent naming conflict between Identity, Grouping and Data
238 <<grouping-namespace>>::
239 YANG namespace containing representation for all `grouping` statements and their
240 child data node statements. Groupings needs to be separated to prevent naming
241 conflict between Identity, Type, Data namespaces.
243 Binding namespace containing representation for all `key` statements.
244 Representations of key statements needs to be in separate namespace, since it is not defined
245 in YANG specification.
247 YANG namespace containing representation of instantiated data tree.
248 Data needs to be separated to prevent naming conflict between Identity, Type,
251 Binding namespace containing Transfer Objects and Builders representing
252 instantiated data tree items.
254 NOTE: Most of Binding Namespaces were introduced to decrease possibility of name
255 conflict between concepts defined in YANG and additional concepts introduced
256 by Binding Specification.
258 === Package hierarchy
260 .Package hierarchy for model
263 |Namespace | Package | Description
265 | <<identity-namespace, Identity>> | `ident`
266 | flat package containing representation for all `identity`
268 .3+| <<type-namespace, Type>> | `type`
269 | flat package containing representations for all top-level
273 | path-based package hierarchy containing representation
274 for `typedef` statements nested in grouping statements, or anonymous types
275 requiring code generation defined inside groupings
278 | path-based package hierarchy containing representation
279 for `typedef` statements nested in grouping statements, or anonymous types
280 requiring code generation defined inside instantiated data nodes
282 | <<key-namespace, Key>> | `key`
283 | path-based package hierarchy containing representation
284 of key statements for grouping code generation defined inside groupings
286 | <<grouping-namespace, Grouping>> | `grp`
287 | path-based package hierarchy containing representation
288 for `grouping` statements and data node statements nested in these groupings
290 | <<data-namespace, Data>> | `data`
291 | path-based package hierarchy containing representation of instantiated
294 | <<dto-namespace, Builder>> | `dto`
295 | path-based package hierarchy containing Tranfer Objects and their builders
296 for instantiated data nodes
304 [[identity-namespace]]
305 === Identity Namespace
311 [[grouping-namespace]]
312 === Grouping Namespace
321 === Builder Namespace
328 [[subpackage-structure]]
329 === Subpackage Naming
336 === `typedef` statement
338 ==== Globally scoped `typedef`
340 ==== Subtree scoped `typedef`
342 Subtree scoped `typedef` statement is type definition, which is not substatement
343 of `module` or `submodule`, and is only visible to child elements of parent
346 * Representation is generated in Type namespace according to following rules:
351 YANG types does not provide single, simple model of behaviour - some times
352 exhibits special properties to extensibility or limiting scope of valid values
356 .Base types and their behaviours
358 | YANG Type | Description | Java Mapping
361 | `binary` | Any binary data | `Binary`?
362 | `bits` | A set of bits or flags | Custom class
363 | `boolean` | `true` or `false` | `Boolean`
364 | `decimal64` | 64-bit signed decimal number | No
365 | `empty` | A leaf that does not have any value | No
366 | `enumeration` | Enumerated strings | No
367 | `identityref` | A reference to an abstract identity | Yes
368 | `instance-identifier` | References a data tree node | Yes
369 | `int8` | 8-bit signed integer | No
370 | `int16` | 16-bit signed integer | No
371 | `int32` | 32-bit signed integer | No
372 | `int64` | 64-bit signed integer | No
373 | `leafref` | A reference to a leaf instance | Maybe
374 | `string` | Human-readable string | No
375 | `uint8` | 8-bit unsigned integer | No
376 | `uint16` | 16-bit unsigned integer | No
377 | `uint32` | 32-bit unsigned integer | No
378 | `uint64` | 64-bit unsigned integer | No
379 | `union` | Choice of member types | Maybe
382 FIXME: Finalize table
397 ==== `enumeration` type
400 ==== `identityref` type
401 ==== `instance-identifier` type
409 Data nodes could be separated into two distinct groups, based on presence of
413 Node, which according to YANG schema does not have child nodes, is leaf node
414 and carries only simple value.
416 Node, which according to YANG schema may have child nodes, node itself does not
417 carry values, values are stored in descendant leaf nodes.
421 === `leaf-list` Statement
424 === `container` Statement
426 Builders will be located in package "dto"
434 container foo-builder {
438 [uml, file="container-builder.png"]
440 set namespaceSeparator none
445 interface data.FooBuilder {
449 In situations where we have a containing element which has as its child a single container, we should make it easy to autobox it. This should not be implemented in the interfaces themselves, but rather should be a method in the associated builder.
453 container example-outter {
454 container example-inner {
469 key "identifier key fookey";
489 [uml, file="list-Keyed.png"]
491 set namespaceSeparator none
494 + getFooIdentifier() : key.foo.FooIdentifier
495 + getFooKey() : key.foo.FooKey
496 + getFooFooKey() : key.foo.FooFooKey
497 + getKey() : key.foo.wrapper.FooKey
500 interface key.foo.wrapper.FooKey {
501 + getFooIdentifier() : key.foo.FooIdentifier
502 + getFooKey() : key.foo.FooKey
503 + getFooFooKey() : key.foo.FooFooKey
506 interface type.foo.identifier.IdentifierUnion
507 interface key.foo.FooIdentifier {
508 + getIdentifier() : type.foo.identifier.IdentifierUnion
511 interface key.foo.FooKey {
515 interface key.foo.FooFooKey {
516 + getFooKey() : String
519 interface data.foo.FooBooNonKey {
520 + getBooNonKey() : String
523 key.foo.FooIdentifier o- type.foo.identifier.IdentifierUnion
525 data.foo.FooBooNonKey -u-|> data.Foo
526 key.foo.wrapper.FooKey -u-|> data.Foo
528 key.foo.FooKey -u-|> data.Foo
529 key.foo.FooFooKey -u-|> data.Foo
530 key.foo.FooIdentifier -u-|> data.Foo
532 key.foo.FooKey -u-|> key.foo.wrapper.FooKey
533 key.foo.FooFooKey -u-|> key.foo.wrapper.FooKey
534 key.foo.FooIdentifier -u-|> key.foo.wrapper.FooKey
537 ==== List without Key
539 === `choice` Statement
551 leaf bar { type string; }
557 [uml, file="case.png"]
559 set namespaceSeparator none
567 + getBase() : data.top.Base;
569 interface data.top.Base
570 interface data.top.base.Foo {
571 + getFoo() : data.top.base.foo.Foo
573 interface data.top.base.foo.Foo
574 interface data.top.base.Bar {
578 data.top.Base -u-|> Choice
579 data.top.base.Foo -u-|> Case
580 data.top.base.Bar -u-|> Case
582 data.top.base.Foo -u-|> data.top.Base
583 data.top.base.Bar -u-|> data.top.Base
585 data.Top o- data.top.Base
586 data.top.base.Foo o- data.top.base.foo.Foo
591 [[instantiated-data-node-rules]]
592 === Instantiated Data Node Rules
595 FIXME: Do we need section per type, or should just general rules be described.
598 ==== `container` Statement
601 FIXME: Here should be Augmentable & Instantiated
604 ==== `leaf` Statement
606 ==== `leaf-list` Statement
608 ==== `choice` Statement
610 ==== `case` Statement
613 FIXME: Here should be Augmentable & Instantiated
616 ==== `list` Statement
619 FIXME: Here should be Augmentable & Instantiated, List signature uses concrete
623 ==== `input` Statement
626 FIXME: Here should be Augmentable & Instantiated
629 ==== `output` Statement
632 FIXME: Here should be Augmentable & Instantiated
635 ==== `notification` Statement
638 FIXME: Here should be Augmentable & Instantiated
641 [[instantiated-data-tree-rules]]
642 === Instantiated Data Tree Rules
645 ==== `container` Statement
648 FIXME: Here should be Augmentable & Instantied & ChildDataNode
652 ==== `leaf` Statement
654 ==== `leaf-list` Statement
656 ==== `case` Statement
659 FIXME: Here should be Augmentable & Instantied & ChildDataNode
662 ==== `list` Statement
665 FIXME: Here should be Augmentable & Instantied & ChildDataNode
668 === `grouping` Statement
670 * `grouping` statement is represented by `interface`
671 ** interface name is generated according to <<class-naming>> with suffix `Grouping`
672 * Representations of `grouping` statements are generated into <<grouping-namespace>>
673 * schema nodes under grouping are represented by `interface` and are generated
674 into <<grouping-namespace>> + name of grouping
675 ** getters (accessors) from parent nodes are generated according to <<accessor-rules>>
676 ** class name is generated according to <<class-naming>> with suffix `Data`
677 ** schema nodes does not follow <<instantiated-data-tree-rules>>, these interfaces
678 are used only in instantiated data tree.
685 grouping simple { <1>
687 leaf bar { type string;} <3>
690 <1> Is represented by interface `grp.SimpleGrouping`
691 <2> Is represented by interface `grp.simple.FooData` and getter in `grp.SimpleGrouping`
692 with signature `public grp.simple.FooData getFoo();`
693 <3> Is represented by getter in `grp.SimpleGrouping` with signature `public String getBar()`
695 [uml, file="grouping1.png"]
697 interface grp.SimpleGrouping {
699 + getFoo() : grp.simple.FooData
701 interface grp.simple.FooData
702 grp.SimpleGrouping o- grp.simple.FooData
706 ==== Data Node substatements
708 Representations of data node substatements are generated according to rules
709 described in <<data-node-rules>> with following changes:
711 MS: proposed interface names:
712 case - <NodeName>Case
713 choice - <<NodeName>Choice
714 container, list - <NodeName>
717 MC: I would keep Data suffix, but idea about distinguishing cases and choices
720 * Interface names for `case`, `choice`, `container` and `list`, is suffixed by
721 `Data` suffix, in order to not conflict with same named groupings inside same
723 ** Getters in parent node, are still generated without `Data` suffix, so
724 the getter signature is in form `FooData getFoo()`
725 ** If return value of getter is constructed using generics (eg. `list`)
726 instead of signature `List<ListItem>` or `Map<ListKey, ListItem>`, wildcarded
727 `? extends ListItem` generic argument are used to allow for overriding during
728 <<uses-statement,instantation of grouping>>.
731 ==== `list` substatement
734 FIXME: Add reasoning / examples for need to use ? extends, instead of directly
738 ==== `leaf-list` susbstatement
741 FIXME: Add reasoning / examples for need to use ? extends, instead of directly
742 using generics for types, which may need instantiation
748 * `uses` statement triggers interface of parent statement to extend (implement)
749 interface of `grouping` referenced by `uses` argument.
750 * As in YANG `uses` statement triggers instatiation of data children of `grouping`
751 which will result in generation of these children as-if they were direct
752 children of parent statement
753 ** data node children are generated according to rules defined for parent statement.
754 Different rules apply based on parent type (instantiated data tree, `input`,
755 `output` or `grouping`)
756 ** interfaces generated for data children extends (implements) interfaces for
757 same children generated for referenced `grouping`
759 .Simple Grouping and Uses
766 leaf bar { type string;}
773 [uml, file="grouping2.png"]
775 set namespaceSeparator none
777 interface grp.SimpleGrouping {
779 + getFoo() : grp.simple.FooData
781 interface grp.simple.FooData
783 + getFoo() : data.top.Foo
785 interface data.top.Foo
787 grp.SimpleGrouping o-- grp.simple.FooData
789 data.Top o-- data.top.Foo
790 data.Top -|> grp.SimpleGrouping
791 data.top.Foo -|> grp.simple.FooData
794 NOTE: Diagram does not show all details for `data.Top` and `data.top.Foo`, which
795 are based on <<instantiated-data-tree-rules>>
799 .Grouping with Nested Grouping
805 grouping with-inner {
817 [uml, file="grouping3.png"]
819 set namespaceSeparator none
821 interface grp.withinner.inner.ContData
822 interface grp.withinner.InnerGrouping {
823 + getCont() : grp.withinner.inner.ContData
827 interface grp.withinner.ContData
829 interface grp.WithInnerGrouping {
830 + getCont() : grp.withinner.ContData
835 + getCont() : data.top.Cont
838 interface data.top.Cont {
841 data.Top o-- data.top.Cont : contains
843 data.Top -|> grp.WithInnerGrouping
844 data.top.Cont -|> grp.withinner.ContData
846 grp.WithInnerGrouping -|> grp.withinner.InnerGrouping : uses (implements)
847 grp.WithInnerGrouping o-- grp.withinner.ContData : contains
848 grp.withinner.InnerGrouping o-- grp.withinner.inner.ContData : contains
850 grp.withinner.ContData -|> grp.withinner.inner.ContData : is concretization of (implements)
854 NOTE: Diagram does not show all details for `data.Top` and `data.top.Cont`, which
855 are based on <<instantiated-data-tree-rules>>
860 ==== `augment` substatement
862 .Uses & Augment in instantiated Data Tree
885 [uml, file="grouping4.png"]
887 set namespaceSeparator none
890 interface data.top.Nested
891 interface data.top.nested.Bar
893 data.Top o-- data.top.Nested
894 data.top.Nested o-- data.top.nested.Bar
896 interface grp.ExampleGrouping
897 interface grp.example.NestedData
900 grp.ExampleGrouping o-- grp.example.NestedData
902 data.Top -|> grp.ExampleGrouping
903 data.top.Nested -|> grp.example.NestedData
906 NOTE: Diagram does not show all details for `data.Top`, `data.top.Nested` and
907 `data.top.nested.Bar`, which are based on <<instantiated-data-tree-rules>>
913 .Uses & Augment in grouping
936 [uml, file="grouping5.png"]
938 set namespaceSeparator none
940 interface grp.TopGrouping
941 interface grp.top.NestedData
942 interface grp.top.nested.BarData
944 grp.TopGrouping o-- grp.top.NestedData
945 grp.top.NestedData o-- grp.top.nested.BarData
947 interface grp.ExampleGrouping
948 interface grp.example.NestedData
950 grp.ExampleGrouping o-- grp.example.NestedData
952 grp.TopGrouping -|> grp.ExampleGrouping
953 grp.top.NestedData -|> grp.example.NestedData
958 === `augment` statement
960 Representation of `augment` statement depends on module in which target node of
961 augment statement is defined
963 * <<uses-augment, augment is substatement of uses>> - data nodes are represented
964 as-if their statements were inlined in target node.
965 See <<uses-augment, uses Statement: augment Substatement>> section for details.
966 * <<augment-same-module,target node in same module as augment>> - data nodes are
967 represented as-if their statements were inlined in target.
968 See <<augment-same-module>> for details & examples.
969 * <<augment-other-module, target node in other module as augment>> - interface representing
970 augmentation is generated, child data nodes are generated by rules for
971 <<instantiated-data-node-rules>>.
972 See <<augment-other-module>> for details & examples.
973 `augment` statement targets only instantiated data nodes, so child data nodes
974 representation is always generated.
976 [[augment-same-module]]
977 ==== Augmentation target in same module
979 All data node children are generated as-if they were directly defined inside
980 target node. There are no externally observable artefacts in generated
981 representation of these nodes, which would point out that they were defined
982 using `augment` statement instead of directly inlining them in target node.
984 .Why augment of same module is same as inlining
987 This rule may seems counterintuitive at first sight, but YANG defines
988 backwards compatibility in terms of effective model instead of way how model
989 is represented. `augment` statement, when targeting node in same module is not
990 externally observable and could factored out by inlining these statements.
992 Definition of `augment` statement in YANG also defines different behaviour when
993 target is same module and allows all features as-if this statements were
997 .Augment with target in same module
999 .YANG module written using augmentations
1012 .Same module written without need to augment
1021 .Same module written with grouping
1033 Java representation for all variants
1034 [uml, file="augment1.png"]
1036 set namespaceSeparator none
1039 interface data.top.Foo
1041 data.Top o- data.top.Foo
1046 [[augment-other-module]]
1047 ==== Augmentation target in other module
1049 .Augment with target in other module
1063 import top { prefix top; }
1065 augment "/top:top" {
1074 [uml,file="augment2.png"]
1076 set namespaceSeparator none
1078 interface Augmentable<T>
1079 interface Augmentation<T>
1081 interface top.data.Top
1082 interface foo.data.FooTop {
1086 interface foo.data.top.Bar
1088 top.data.Top -u-|> Augmentable : T = top.data.Top
1089 foo.data.FooTop -u-|> Augmentation : T = top.data.Top
1090 top.data.Top o-- foo.data.FooTop
1091 foo.data.FooTop o-- foo.data.top.Bar
1096 .Multiple augments with same target
1110 import top { prefix top; }
1112 augment "/top:top" {
1118 augment "/top:top" {
1127 [uml,file="augment3.png"]
1129 set namespaceSeparator none
1131 interface Augmentable<T>
1132 interface Augmentation<T>
1134 interface top.data.Top
1135 interface foo.data.FooTop {
1140 interface foo.data.top.Bar
1141 interface foo.data.top.Baz
1143 top.data.Top -u-|> Augmentable : T = top.data.Top
1144 foo.data.FooTop -u-|> Augmentation : T = top.data.Top
1145 top.data.Top o-- foo.data.FooTop
1146 foo.data.FooTop o-- foo.data.top.Bar
1147 foo.data.FooTop o-- foo.data.top.Baz
1152 .Multiple augments with different targets
1170 import target { prefix t; }
1172 augment "/t:first" {
1178 augment "/t:second" {
1187 [uml, file="augment4.png"]
1189 set namespaceSeparator none
1191 interface Augmentable<T>
1192 interface Augmentation<T>
1194 interface target.data.First
1195 interface target.data.Second
1197 interface foo.data.FooFirst {
1200 interface foo.data.FooSecond {
1204 interface foo.data.first.Bar
1205 interface foo.data.second.Baz
1207 target.data.First -u-|> Augmentable : T = target.data.First
1208 target.data.Second -u-|> Augmentable : T = target.data.Second
1210 foo.data.FooFirst -u-|> Augmentation : T = target.data.First
1211 foo.data.FooSecond -u-|> Augmentation : T = target.data.Second
1214 target.data.First o-- foo.data.FooFirst
1215 target.data.Second o-- foo.data.FooSecond
1217 foo.data.FooFirst o-- foo.data.first.Bar
1218 foo.data.FooSecond o-- foo.data.second.Baz
1236 grouping key.grp.nodes.node.<nodeidentifier>
1238 instantiated key.data.nodes.node.<nodeidentifier>