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