BUG-1411: MDSAL Binding2 Spec - comments/feedback fixed
[mdsal.git] / binding2 / mdsal-binding2-spec / src / site / asciidoc / binding-2.adoc
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
4 :toc:
5 :toclevels: 4
6
7 == Introduction
8
9 === Terminology
10
11 Namespace::
12   naming space, in which all identifiers needs to be unique
13 identifiers.
14 Data Node::
15 Data Tree::
16 Instance Identifier::
17 Instantiated Data Node::
18 Instantiated Data Tree::
19 Transfer Object::
20 Builder::
21   builder
22
23 === Binding Specification v2 Concepts
24
25 <<Instantiable>>::
26   Represent node, which is instantiable by users as a part of notification,
27   rpc, action or data tree.
28 <<TreeNode>>::
29   Represents node, which is part of instantiated data tree, this interface
30   is not used directly, but rather via <<TreeChildNode>>. See <<instantiated-data-tree-rules>>
31   for more information.
32 <<TreeRoot>>::
33   Represents virtual root of instantiated data tree.
34 <<TreeChildNode>>::
35   Represents node, which is part of instantiated data tree and is not root of
36   data tree.
37 <<Augmentable>>::
38   Represents instantiated node, which is subjectible to be extended / augmented
39   by `augment` statement from external module.
40 <<Augmentation>>::
41   Represents extension to instantiated node, which is introduced from different
42   model than instantiated node.
43 <<InstanceIdentifier>>::
44   Unique identifier of node / subtree in data tree, which provides unambiguous
45   information, how to reference node / subtree in Instantiated Data Tree.
46
47
48 [cols="6"]
49 |===
50 .2+|Statement .2+| In groupings 3+| Instantiable .2+| Augmentable
51 | In Data | In RPC | In Notification
52
53 | `grouping` | Yes | No | No | No | No
54
55 | `container` | Yes | Yes | Yes | Yes | Yes
56
57 | `leaf` | Yes | Yes | Yes | Yes | No
58
59 | `leaf-list` | Yes | Yes | Yes | Yes | No
60
61 | `list` | Yes | Yes | Yes | Yes | Yes
62
63 | `anydata` | Yes | Yes | Yes | Yes | No
64
65 | `anyxml` | Yes | Yes | Yes | Yes | No
66
67 | `choice` | Yes | Yes | Yes | Yes | Yes
68
69 | `case` | Yes | Yes | Yes | Yes | Yes
70
71 | `input` | Yes | No | Yes | No | Yes
72
73 | `output` | Yes | No | Yes | No | Yes
74
75 | `notification` | Yes | No | No | Yes | Yes
76
77 |===
78
79 == Namespaces
80
81 YANG defines several namespaces and naming space of YANG is wider then applicable
82 namespace of JAVA language. In order to decrease conflicts between various
83 YANG-defined namespaces and classes introduced by Binding Specification, it
84 is needed to:
85
86 * separate namespaces by Java package hierarchy
87 ** each namespace must define rules how to construct package name, which
88    will not conflict with other namespace
89 * if multiple classes are generated for YANG statement they need to be in separate
90   packages to decrease possible conflicts with siblings.
91 * if Binding Specification introduces new concepts, which does not have explicit
92   namespace rules in YANG, these concepts needs to be in their own, separate
93   namespaces, in order to not conflict on valid YANG namespace items.
94
95
96 This rules allows to identify two types of namespaces:
97
98 .Namespace types by source of namespace
99 YANG namespace::
100   Naming space explicitly defined in YANG specification, which needs to be
101   explicitly supported in order to prevent naming conflicts.
102 Binding namespace::
103   Naming space introduced by Binding Specification for additional properties
104   and functionality of Binding Specification. This namespaces needs to be separate
105   from YANG namespaces in order to not have naming conflict with YANG-derived.
106
107
108 Binding Specification v2 uses following namespaces:
109
110 .Concrete namespaces used in Binding Specification
111 <<module-namespace>>::
112   YANG namespace containing representation for all modules.
113 <<identity-namespace>>::
114   YANG namespace containing representation for all `identity` statements. Identities
115   needs to be separated to prevent naming conflict between Grouping, Data, Type
116   namespaces.
117 <<type-namespace>>::
118   YANG namespace containing representation for all `typedef` statements and
119   annonymous definitions of `union`, `enumeration` and `bits` types. Types needs
120   to be seperated to prevent naming conflict between Identity, Grouping and Data
121   namespaces.
122 <<grouping-namespace>>::
123   YANG namespace containing representation for all `grouping` statements and their
124   child data node statements. Groupings needs to be separated to prevent naming
125   conflict between Identity, Type, Data namespaces.
126 <<key-namespace>>::
127   Binding namespace containing representation for all `key` statements.
128   Representations of key statements needs to be in separate namespace, since it is not defined
129   in YANG specification.
130 <<data-namespace>>::
131   YANG namespace containing representation of instantiated data tree.
132   Data needs to be separated to prevent naming conflict between Identity, Type,
133   Grouping namespaces.
134 <<dto-namespace>>::
135   Binding namespace containing Transfer Objects and Builders representing
136   instantiated data tree items.
137
138 NOTE: Most of Binding Namespaces were introduced to decrease possibility of name
139 conflict between concepts defined in YANG and additional concepts introduced
140 by Binding Specification.
141
142 === Package hierarchy
143
144 .Package hierarchy for model
145 [cols="1,1,4"]
146 |===
147 |Namespace | Package  | Description
148
149 | <<identity-namespace, Identity>> | `ident`
150 | flat package containing representation for all `identity`
151
152 .3+| <<type-namespace, Type>> | `type`
153 | flat package containing representations for all top-level
154    `typedef` statements
155
156 | `type.grp`
157 | path-based package hierarchy containing representation
158   for `typedef` statements nested in grouping statements, or anonymous types
159   requiring code generation defined inside groupings
160
161 | `type.data`
162 | path-based package hierarchy containing representation
163   for `typedef` statements nested in grouping statements, or anonymous types
164   requiring code generation defined inside instantiated data nodes
165
166 |  <<key-namespace, Key>> | `key`
167 | path-based package hierarchy containing representation
168   of key statements for grouping code generation defined inside groupings
169
170 | <<grouping-namespace, Grouping>> | `grp`
171 | path-based package hierarchy containing representation
172   for `grouping` statements and data node statements nested in these groupings
173
174 | <<data-namespace, Data>> | `data`
175 | path-based package hierarchy containing representation of instantiated
176   data nodes
177
178 | <<dto-namespace, Builder>> | `dto`
179 | path-based package hierarchy containing Tranfer Objects and their builders
180   for instantiated data nodes
181 |===
182
183 [[module-namespace]]
184 === Module Namespace
185
186
187
188 [[identity-namespace]]
189 === Identity Namespace
190
191
192 [[type-namespace]]
193 === Type Namespace
194
195 [[grouping-namespace]]
196 === Grouping Namespace
197
198 [[key-namespace]]
199 === Key Namespace
200
201 [[data-namespace]]
202 === Data Namespace
203
204 [[dto-namespace]]
205 === Builder Namespace
206
207 == Generic rules
208
209 [[class-naming]]
210 === Class Naming
211
212 [[subpackage-structure]]
213 === Subpackage Naming
214
215 [[accessor-rules]]
216 === Accessor rules
217
218 == Type rules
219
220 === `typedef` statement
221
222 ==== Globally scoped `typedef`
223
224 ==== Subtree scoped `typedef`
225
226 Subtree scoped `typedef` statement is type definition, which is not substatement
227 of `module` or `submodule`, and is only visible to child elements of parent
228 statement.
229
230 * Representation is generated in Type namespace according to following rules:
231
232
233 === Type mapping
234
235 YANG types does not provide single, simple model of behaviour - some times
236 exhibits special properties to extensibility or limiting scope of valid values
237 when type is derived
238
239 ////
240 .Base types and their behaviours
241 |===
242 | YANG Type | Description | Java Mapping
243
244
245 | `binary`              | Any binary data | `Binary`?
246 | `bits`                | A set of bits or flags | Custom class
247 | `boolean`             | `true` or `false` | `Boolean`
248 | `decimal64`           | 64-bit signed decimal number  | No
249 | `empty`               | A leaf that does not have any value | No
250 | `enumeration`         | Enumerated strings | No
251 | `identityref`         | A reference to an abstract identity | Yes
252 | `instance-identifier` | References a data tree node | Yes
253 | `int8`                | 8-bit signed integer | No
254 | `int16`               | 16-bit signed integer | No
255 | `int32`               | 32-bit signed integer | No
256 | `int64`               | 64-bit signed integer | No
257 | `leafref`             | A reference to a leaf instance | Maybe
258 | `string`              | Human-readable string | No
259 | `uint8`               | 8-bit unsigned integer | No
260 | `uint16`              | 16-bit unsigned integer | No
261 | `uint32`              | 32-bit unsigned integer | No
262 | `uint64`              | 64-bit unsigned integer | No
263 | `union`               | Choice of member types | Maybe
264
265 |===
266 FIXME: Finalize table
267 ////
268
269 ==== `boolean` type
270 ==== `empty` type
271 ==== `int8` type
272 ==== `int16` type
273 ==== `int32` type
274 ==== `int64` type
275 ==== `uint8` type
276 ==== `uint16` type
277 ==== `uint32` type
278 ==== `uint64` type
279 ==== `string` type
280 ==== `binary` type
281 ==== `enumeration` type
282 ==== `bits` type
283
284 ==== `identityref` type
285 ==== `instance-identifier` type
286
287 ==== `leafref` type
288 ==== `union` type
289
290 [[data-node-rules]]
291 == Data Node rules
292
293 Data nodes could be separated into two distinct groups, based on presence of
294 child nodes:
295
296 Leaf node::
297   Node, which according to YANG schema does not have child nodes, is leaf node
298   and carries only simple value.
299 Interior node::
300   Node, which according to YANG schema may have child nodes, node itself does not
301   carry values, values are stored in descendant leaf nodes.
302
303 === `leaf` Statement
304
305 === `leaf-list` Statement
306
307
308 === `container` Statement
309
310 Builders will be located in package "dto"
311
312
313 [source,yang]
314 ----
315 container foo {
316 }
317
318 container foo-builder {
319 }
320 ----
321
322 [uml, file="container-builder.png"]
323 --
324 set namespaceSeparator none
325
326 interface data.Foo {
327 }
328
329 interface data.FooBuilder {
330 }
331 --
332
333 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.
334
335 [source,yang]
336 ----
337 container example-outter {
338     container example-inner {
339         leaf example {
340             type string;
341         }
342     }
343 }
344 ----
345
346 === `list` Statement
347
348 ==== Keyed List
349
350 [source,yang]
351 ----
352 list foo {
353     key identifier key fookey;
354     leaf identifier {
355         type union {
356             type string;
357         }
358     }
359
360     leaf key {
361         type string;
362     }
363
364     leaf fookey {
365         type string;
366     }
367 }
368 ----
369 [uml, file="list-Keyed.png"]
370 --
371 set namespaceSeparator none
372
373 interface data.Foo {
374 }
375
376 interface key.foo.FooIdentifier {
377 }
378
379 interface key.foo.FooKey {
380 }
381
382 interface key.foo.FooFooKey {
383 }
384
385 interface type.foo.identifier.IdentifierUnion {
386 }
387
388 data.Foo o- key.foo.FooIdentifier
389 data.Foo o- key.foo.FooKey
390 data.Foo o- key.foo.FooFooKey
391 key.foo.FooIdentifier o- type.foo.identifier.IdentifierUnion
392 --
393
394 ==== List without Key
395
396 === `choice` Statement
397
398 === `case` Statement
399
400 [source,yang]
401 ----
402 container top {
403   choice base {
404     case foo {
405       container foo;
406     }
407     case bar {
408       leaf bar { type string; }
409     }
410   }
411 }
412 ----
413
414 [uml, file="case.png"]
415 --
416 set namespaceSeparator none
417
418 package spec {
419   interface Choice
420   interface Case
421 }
422
423 interface data.Top {
424   + getBase() : data.top.Base;
425 }
426 interface data.top.Base
427 interface data.top.base.Foo {
428   + getFoo() : data.top.base.foo.Foo
429 }
430 interface data.top.base.foo.Foo
431 interface data.top.base.Bar {
432   + getBar() : String
433 }
434
435 data.top.Base -u-|> Choice
436 data.top.base.Foo -u-|> Case
437 data.top.base.Bar -u-|> Case
438
439 data.top.base.Foo -u-|> data.top.Base
440 data.top.base.Bar -u-|> data.top.Base
441
442 data.Top o- data.top.Base
443 data.top.base.Foo o- data.top.base.foo.Foo
444 --
445
446 == Specific rules
447
448 [[instantiated-data-node-rules]]
449 === Instantiated Data Node Rules
450
451 ////
452 FIXME: Do we need section per type, or should just general rules be described.
453 ////
454
455 ==== `container` Statement
456
457 ////
458 FIXME: Here should be Augmentable & Instantiated
459 ////
460
461 ==== `leaf` Statement
462
463 ==== `leaf-list` Statement
464
465 ==== `choice` Statement
466
467 ==== `case` Statement
468
469 ////
470 FIXME: Here should be Augmentable & Instantiated
471 ////
472
473 ==== `list` Statement
474
475 ////
476 FIXME: Here should be Augmentable & Instantiated, List signature uses concrete
477 interfaces
478 ////
479
480 ==== `input` Statement
481
482 ////
483 FIXME: Here should be Augmentable & Instantiated
484 ////
485
486 ==== `output` Statement
487
488 ////
489 FIXME: Here should be Augmentable & Instantiated
490 ////
491
492 ==== `notification` Statement
493
494 ////
495 FIXME: Here should be Augmentable & Instantiated
496 ////
497
498 [[instantiated-data-tree-rules]]
499 === Instantiated Data Tree Rules
500
501
502 ==== `container` Statement
503
504 ////
505 FIXME: Here should be Augmentable & Instantied & ChildDataNode
506 ////
507
508
509 ==== `leaf` Statement
510
511 ==== `leaf-list` Statement
512
513 ==== `case` Statement
514
515 ////
516 FIXME: Here should be Augmentable & Instantied & ChildDataNode
517 ////
518
519 ==== `list` Statement
520
521 ////
522 FIXME: Here should be Augmentable & Instantied & ChildDataNode
523 ////
524
525 === `grouping` Statement
526
527 * `grouping` statement is represented by `interface`
528 ** interface name is generated according to <<class-naming>> with suffix `Grouping`
529 * Representations of `grouping` statements are generated into <<grouping-namespace>>
530 * schema nodes under grouping are represented by `interface` and are generated
531   into <<grouping-namespace>> + name of grouping
532 ** getters (accessors) from parent nodes are generated according to <<accessor-rules>>
533 ** class name is generated according to <<class-naming>> with suffix `Data`
534 ** schema nodes does not follow <<instantiated-data-tree-rules>>, these interfaces
535    are used only in instantiated data tree.
536
537 .Simple Grouping
538 ====
539 .YANG Snippet
540 [source, yang]
541 ----
542 grouping simple  { <1>
543   container foo; <2>
544   leaf bar { type string;} <3>
545 }
546 ----
547 <1> Is represented by interface `grp.SimpleGrouping`
548 <2> Is represented by interface `grp.simple.FooData` and getter in `grp.SimpleGrouping`
549     with signature `public grp.simple.FooData getFoo();`
550 <3> Is represented by getter in `grp.SimpleGrouping` with signature `public String getBar()`
551
552 [uml, file="grouping1.png"]
553 --
554 interface grp.SimpleGrouping {
555   + getBar() : String
556   + getFoo() : grp.simple.FooData
557 }
558 interface grp.simple.FooData
559 grp.SimpleGrouping o- grp.simple.FooData
560 --
561 ====
562
563 ==== Data Node substatements
564
565 Representations of data node substatements are generated according to rules
566 described in <<data-node-rules>> with following changes:
567 ////
568 MS: proposed interface names:
569 case - <NodeName>Case
570 choice - <<NodeName>Choice
571 container, list - <NodeName>
572 ////
573 ////
574 MC: I would keep Data suffix, but idea about distinguishing cases and choices
575 is to think about
576 ////
577 * Interface names for `case`, `choice`, `container` and `list`, is suffixed by
578   `Data` suffix, in order to not conflict with same named groupings inside same
579   package
580 ** Getters in parent node, are still generated without `Data` suffix, so
581    the getter signature is in form `FooData getFoo()`
582 **  If return value of getter is constructed using generics (eg. `list`)
583     instead of signature `List<ListItem>` or `Map<ListKey, ListItem>`, wildcarded
584     `? extends ListItem` generic argument are used to allow for overriding during
585     <<uses-statement,instantation of grouping>>.
586
587
588 ==== `list` substatement
589
590 ////
591 FIXME: Add reasoning / examples for need to use ? extends, instead of directly
592 using generics.
593 ////
594
595 ==== `leaf-list` susbstatement
596
597 ////
598 FIXME: Add reasoning / examples for need to use ? extends, instead of directly
599 using generics for types, which may need instantiation
600 ////
601
602 [[uses-statement]]
603 === `uses` Statement
604
605 * `uses` statement triggers interface of parent statement to extend (implement)
606   interface of `grouping` referenced by `uses` argument.
607 * As in YANG `uses` statement triggers instatiation of data children of `grouping`
608   which will result in generation of these children as-if they were direct
609   children of parent statement
610 **  data node children are generated according to rules defined for parent statement.
611     Different rules apply based on parent type (instantiated data tree, `input`,
612     `output` or `grouping`)
613 **  interfaces generated for data children extends (implements) interfaces for
614     same children generated for referenced `grouping`
615
616 .Simple Grouping and Uses
617 ====
618 .YANG Snippet
619 [source, yang]
620 ----
621 grouping simple  {
622   container foo;
623   leaf bar { type string;}
624 }
625
626 container top {
627   uses simple;
628 }
629 ----
630 [uml, file="grouping2.png"]
631 --
632 set namespaceSeparator none
633
634 interface grp.SimpleGrouping {
635   + getBar() : String
636   + getFoo() : grp.simple.FooData
637 }
638 interface grp.simple.FooData
639 interface data.Top {
640   + getFoo() : data.top.Foo
641 }
642 interface data.top.Foo
643
644 grp.SimpleGrouping o-- grp.simple.FooData
645
646 data.Top o-- data.top.Foo
647 data.Top -|> grp.SimpleGrouping
648 data.top.Foo -|> grp.simple.FooData
649 --
650
651 NOTE: Diagram does not show all details for `data.Top` and `data.top.Foo`, which
652 are based on <<instantiated-data-tree-rules>>
653
654 ====
655
656 .Grouping with Nested Grouping
657 ====
658
659 .YANG Snippet
660 [source, yang]
661 ----
662 grouping with-inner {
663   grouping inner {
664     container cont;
665   }
666   uses inner;
667 }
668
669 container top {
670   uses with-inner;
671 }
672 ----
673
674 [uml, file="grouping3.png"]
675 --
676 set namespaceSeparator none
677
678 interface grp.withinner.inner.ContData
679 interface grp.withinner.InnerGrouping {
680   + getCont() : grp.withinner.inner.ContData
681 }
682
683
684 interface grp.withinner.ContData
685
686 interface grp.WithInnerGrouping {
687   + getCont() : grp.withinner.ContData
688 }
689
690
691 interface data.Top {
692   + getCont() : data.top.Cont
693 }
694
695 interface data.top.Cont {
696
697 }
698 data.Top o-- data.top.Cont : contains
699
700 data.Top -|> grp.WithInnerGrouping
701 data.top.Cont -|> grp.withinner.ContData
702
703 grp.WithInnerGrouping -|> grp.withinner.InnerGrouping : uses (implements)
704 grp.WithInnerGrouping o-- grp.withinner.ContData : contains
705 grp.withinner.InnerGrouping o-- grp.withinner.inner.ContData : contains
706
707 grp.withinner.ContData -|> grp.withinner.inner.ContData : is concretization of (implements)
708
709 --
710
711 NOTE: Diagram does not show all details for `data.Top`  and `data.top.Cont`, which
712 are based on <<instantiated-data-tree-rules>>
713
714 ====
715
716 [[uses-augment]]
717 ==== `augment` substatement
718
719 .Uses & Augment in instantiated Data Tree
720 ====
721 [source,yang]
722 ----
723 grouping example {
724   container nested {
725     leaf foo {
726       type string;
727     }
728   }
729 }
730
731 container top {
732   uses example {
733     augment nested {
734       container bar {
735       }
736     }
737   }
738 }
739
740 ----
741
742 [uml, file="grouping4.png"]
743 --
744 set namespaceSeparator none
745
746 interface data.Top
747 interface data.top.Nested
748 interface data.top.nested.Bar
749
750 data.Top o-- data.top.Nested
751 data.top.Nested o-- data.top.nested.Bar
752
753 interface grp.ExampleGrouping
754 interface grp.example.NestedData
755
756
757 grp.ExampleGrouping o-- grp.example.NestedData
758
759 data.Top -|> grp.ExampleGrouping
760 data.top.Nested -|> grp.example.NestedData
761 --
762
763 NOTE: Diagram does not show all details for `data.Top`, `data.top.Nested` and
764 `data.top.nested.Bar`, which are based on <<instantiated-data-tree-rules>>
765
766
767 ====
768
769
770 .Uses & Augment in grouping
771 ====
772 [source,yang]
773 ----
774 grouping example {
775   container nested {
776     leaf foo {
777       type string;
778     }
779   }
780 }
781
782 grouping top {
783   uses example {
784     augment nested {
785       container bar {
786       }
787     }
788   }
789 }
790
791 ----
792
793 [uml, file="grouping5.png"]
794 --
795 set namespaceSeparator none
796
797 interface grp.TopGrouping
798 interface grp.top.NestedData
799 interface grp.top.nested.BarData
800
801 grp.TopGrouping o-- grp.top.NestedData
802 grp.top.NestedData o-- grp.top.nested.BarData
803
804 interface grp.ExampleGrouping
805 interface grp.example.NestedData
806
807 grp.ExampleGrouping o-- grp.example.NestedData
808
809 grp.TopGrouping -|> grp.ExampleGrouping
810 grp.top.NestedData -|> grp.example.NestedData
811 --
812
813 ====
814
815 === `augment` statement
816
817 Representation of `augment` statement depends on module in which target node of
818 augment statement is defined
819
820 * <<uses-augment, augment is substatement of uses>> - data nodes are represented
821   as-if their statements were inlined in target node.
822   See <<uses-augment, uses Statement: augment Substatement>> section for details.
823 * <<augment-same-module,target node in same module as augment>> - data nodes are
824   represented as-if their statements were inlined in target.
825   See <<augment-same-module>> for details & examples.
826 * <<augment-other-module, target node in other module as augment>> - interface representing
827   augmentation is generated, child data nodes are generated by rules for
828   <<instantiated-data-node-rules>>.
829   See <<augment-other-module>> for details & examples.
830 `augment` statement targets only instantiated data nodes, so child data nodes
831 representation is always generated.
832
833 [[augment-same-module]]
834 ==== Augmentation target in same module
835
836 All data node children are generated as-if they were directly defined inside
837 target node. There are no externally observable artefacts in generated
838 representation of these nodes, which would point out that they were defined
839 using `augment` statement instead of directly inlining them in target node.
840
841 .Why augment of same module is same as inlining
842 [IMPORTANT]
843 ====
844 This rule may seems counterintuitive at first sight, but YANG defines
845 backwards compatibility in terms of effective model instead of way how model
846 is represented. `augment` statement, when targeting node in same module is not
847 externally observable and could factored out by inlining these statements.
848
849 Definition of `augment` statement in YANG also defines different behaviour when
850 target is same module and allows all features as-if this statements were
851 directly inlined.
852 ====
853
854 .Augment with target in same module
855 ====
856 .YANG module written using augmentations
857 [source,yang]
858 ----
859 container top {
860
861 }
862
863 augment "/top" {
864   container foo {
865
866   }
867 }
868 ----
869 .Same module written without need to augment
870 ----
871 container top {
872   container foo {
873
874   }
875 }
876
877 ----
878 .Same module written with grouping
879 ----
880 grouping a {
881     container foo {
882     }
883 }
884
885 container top {
886     uses a;
887 }
888
889 ----
890 Java representation for all variants
891 [uml, file="augment1.png"]
892 --
893 set namespaceSeparator none
894
895 interface data.Top
896 interface data.top.Foo
897
898 data.Top o- data.top.Foo
899 --
900
901 ====
902
903 [[augment-other-module]]
904 ==== Augmentation target in other module
905
906 .Augment with target in other module
907 ====
908 [source,yang]
909 ----
910 module top {
911   ...
912
913   container top {
914
915   }
916 }
917
918 module foo {
919   ...
920   import top { prefix top; }
921   ...
922   augment "/top:top" {
923     container bar {
924
925     }
926   }
927 }
928
929 ----
930
931 [uml,file="augment2.png"]
932 --
933 set namespaceSeparator none
934
935 interface Augmentable<T>
936 interface Augmentation<T>
937
938 interface top.data.Top
939 interface foo.data.FooTop  {
940   + getBar() : Bar
941 }
942
943 interface foo.data.top.Bar
944
945 top.data.Top -u-|> Augmentable : T = top.data.Top
946 foo.data.FooTop -u-|> Augmentation : T = top.data.Top
947 top.data.Top o-- foo.data.FooTop
948 foo.data.FooTop o-- foo.data.top.Bar
949 --
950
951 ====
952
953 .Multiple augments with same target
954 ====
955 [source,yang]
956 ----
957 module top {
958   ...
959
960   container top {
961
962   }
963 }
964
965 module foo {
966   ...
967   import top { prefix top; }
968   ...
969   augment "/top:top" {
970     container bar {
971
972     }
973   }
974
975   augment "/top:top" {
976     container baz {
977
978     }
979   }
980 }
981
982 ----
983
984 [uml,file="augment3.png"]
985 --
986 set namespaceSeparator none
987
988 interface Augmentable<T>
989 interface Augmentation<T>
990
991 interface top.data.Top
992 interface foo.data.FooTop {
993   + getBar() : Bar
994   + getBaz() : Baz
995 }
996
997 interface foo.data.top.Bar
998 interface foo.data.top.Baz
999
1000 top.data.Top -u-|> Augmentable : T = top.data.Top
1001 foo.data.FooTop -u-|> Augmentation : T = top.data.Top
1002 top.data.Top o-- foo.data.FooTop
1003 foo.data.FooTop o-- foo.data.top.Bar
1004 foo.data.FooTop o-- foo.data.top.Baz
1005 --
1006
1007 ====
1008
1009 .Multiple augments with different targets
1010 ====
1011 [source,yang]
1012 ----
1013 module target {
1014   ...
1015
1016   container first {
1017
1018   }
1019
1020   container second {
1021
1022   }
1023 }
1024
1025 module foo {
1026   ...
1027   import target { prefix t; }
1028   ...
1029   augment "/t:first" {
1030     container bar {
1031
1032     }
1033   }
1034
1035   augment "/t:second" {
1036     container baz {
1037
1038     }
1039   }
1040 }
1041
1042 ----
1043
1044 [uml, file="augment4.png"]
1045 --
1046 set namespaceSeparator none
1047
1048 interface Augmentable<T>
1049 interface Augmentation<T>
1050
1051 interface target.data.First
1052 interface target.data.Second
1053
1054 interface foo.data.FooFirst {
1055   + getBar() : Bar
1056 }
1057 interface foo.data.FooSecond {
1058   + getBaz() : Baz
1059 }
1060
1061 interface foo.data.first.Bar
1062 interface foo.data.second.Baz
1063
1064 target.data.First -u-|> Augmentable : T = target.data.First
1065 target.data.Second -u-|> Augmentable : T = target.data.Second
1066
1067 foo.data.FooFirst -u-|> Augmentation : T = target.data.First
1068 foo.data.FooSecond -u-|> Augmentation : T = target.data.Second
1069
1070
1071 target.data.First o-- foo.data.FooFirst
1072 target.data.Second o-- foo.data.FooSecond
1073
1074 foo.data.FooFirst o-- foo.data.first.Bar
1075 foo.data.FooSecond o-- foo.data.second.Baz
1076 --
1077 ====
1078
1079 .Key in grouping
1080 ====
1081 [source,yang]
1082 ----
1083 grouping nodes {
1084     list node {
1085         key id;
1086         leaf id {
1087             type string;
1088         }
1089     }
1090 }
1091
1092 ----
1093 grouping key.grp.nodes.node.<nodeidentifier>
1094
1095 instantiated key.data.nodes.node.<nodeidentifier>