Merge "Bug 1531: Fixed incorrect use of leaf types in BindingGeneratorImpl"
[mdsal.git] / code-generator / binding-generator-impl / src / main / java / org / opendaylight / yangtools / sal / binding / generator / impl / YangTemplate.xtend
1 /*
2  * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.yangtools.sal.binding.generator.impl
9
10 import java.text.SimpleDateFormat
11 import java.util.Collection
12 import java.util.Date
13 import java.util.List
14 import java.util.Map
15 import java.util.Set
16 import java.util.StringTokenizer
17 import org.opendaylight.yangtools.yang.common.QName
18 import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode
19 import org.opendaylight.yangtools.yang.model.api.AugmentationSchema
20 import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode
21 import org.opendaylight.yangtools.yang.model.api.ChoiceNode
22 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode
23 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode
24 import org.opendaylight.yangtools.yang.model.api.Deviation
25 import org.opendaylight.yangtools.yang.model.api.ExtensionDefinition
26 import org.opendaylight.yangtools.yang.model.api.FeatureDefinition
27 import org.opendaylight.yangtools.yang.model.api.GroupingDefinition
28 import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode
29 import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode
30 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode
31 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode
32 import org.opendaylight.yangtools.yang.model.api.Module
33 import org.opendaylight.yangtools.yang.model.api.ModuleImport
34 import org.opendaylight.yangtools.yang.model.api.NotificationDefinition
35 import org.opendaylight.yangtools.yang.model.api.RpcDefinition
36 import org.opendaylight.yangtools.yang.model.api.SchemaNode
37 import org.opendaylight.yangtools.yang.model.api.SchemaPath
38 import org.opendaylight.yangtools.yang.model.api.TypeDefinition
39 import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode
40 import org.opendaylight.yangtools.yang.model.api.UsesNode
41 import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition
42 import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition.EnumPair
43
44 class YangTemplate {
45
46     private static var Module module = null
47
48     def static String generateYangSnipet(SchemaNode schemaNode) {
49         if (schemaNode == null)
50             return ''
51
52         '''
53             «IF schemaNode instanceof DataSchemaNode»
54             «writeDataSchemaNode(schemaNode as DataSchemaNode)»
55             «ENDIF»
56             «IF schemaNode instanceof EnumTypeDefinition.EnumPair»
57             «writeEnumPair(schemaNode as EnumTypeDefinition.EnumPair)»
58             «ENDIF»
59             «IF schemaNode instanceof ExtensionDefinition»
60             «writeExtension(schemaNode as ExtensionDefinition)»
61             «ENDIF»
62             «IF schemaNode instanceof FeatureDefinition»
63             «writeFeature(schemaNode as FeatureDefinition)»
64             «ENDIF»
65             «IF schemaNode instanceof GroupingDefinition»
66             «writeGroupingDef(schemaNode as GroupingDefinition)»
67             «ENDIF»
68             «IF schemaNode instanceof IdentitySchemaNode»
69             «writeIdentity(schemaNode as IdentitySchemaNode)»
70             «ENDIF»
71             «IF schemaNode instanceof NotificationDefinition»
72             «writeNotification(schemaNode as NotificationDefinition)»
73             «ENDIF»
74             «IF schemaNode instanceof RpcDefinition»
75             «writeRPC(schemaNode as RpcDefinition)»
76             «ENDIF»
77             «IF schemaNode instanceof TypeDefinition<?>»
78             «writeTypeDefinition(schemaNode as TypeDefinition<?>)»
79             «ENDIF»
80             «IF schemaNode instanceof UnknownSchemaNode»
81             «writeUnknownSchemaNode(schemaNode as UnknownSchemaNode)»
82             «ENDIF»
83         '''
84     }
85     
86     def static String generateYangSnipet(Set<? extends SchemaNode> nodes) {
87         if (nodes.nullOrEmpty)
88             return ''
89         
90         '''
91             «FOR node : nodes»
92                 «IF node instanceof NotificationDefinition»
93                 «writeNotification(node as NotificationDefinition)»
94                 «ELSEIF node instanceof RpcDefinition»
95                 «writeRPC(node as RpcDefinition)»
96                 «ENDIF»
97             «ENDFOR»
98         '''
99     }
100
101     def static writeEnumPair(EnumPair pair) {
102         var boolean hasEnumPairValue = pair.value != null
103         '''
104             enum «pair.name»«IF !hasEnumPairValue»;«ELSE»{
105                 value «pair.value»;
106             }
107             «ENDIF»
108         '''
109     }
110
111     def static String writeModuleImports(Set<ModuleImport> moduleImports) {
112         if (moduleImports.nullOrEmpty)
113             return ''
114
115         '''
116             «FOR moduleImport : moduleImports SEPARATOR "\n"»
117                 «IF moduleImport != null && !moduleImport.moduleName.nullOrEmpty»
118                 import «moduleImport.moduleName» { prefix "«moduleImport.prefix»"; }
119                 «ENDIF»
120             «ENDFOR»
121         '''
122     }
123
124     def static formatDate(Date moduleRevision) {
125         val SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-mm-dd")
126         return dateFormat.format(moduleRevision)
127     }
128
129     def static writeRevision(Date moduleRevision, String moduleDescription) {
130         val revisionIndent = 12
131
132         '''
133             revision «formatDate(moduleRevision)» {
134                 description "«formatToParagraph(moduleDescription, revisionIndent)»";
135             }
136         '''
137     }
138
139     def static String generateYangSnipet(Module module) {
140
141         '''
142             module «module.name» {
143                 yang-version «module.yangVersion»;
144                 namespace "«module.QNameModule.namespace.toString»";
145                 prefix "«module.prefix»";
146
147                 «IF !module.imports.nullOrEmpty»
148                 «writeModuleImports(module.imports)»
149                 «ENDIF»
150                 «IF module.revision != null»
151                 «writeRevision(module.revision, module.description)»
152                 «ENDIF»
153                 «IF !module.childNodes.nullOrEmpty»
154
155                 «writeDataSchemaNodes(module.childNodes)»
156                 «ENDIF»
157                 «IF !module.groupings.nullOrEmpty»
158
159                 «writeGroupingDefs(module.groupings)»
160                 «ENDIF»
161                 «IF !module.augmentations.nullOrEmpty»
162
163                 «writeAugments(module.augmentations)»
164                 «ENDIF»
165                 «IF !module.deviations.nullOrEmpty»
166
167                 «writeDeviations(module.deviations)»
168                 «ENDIF»
169                 «IF !module.extensionSchemaNodes.nullOrEmpty»
170
171                 «writeExtensions(module.extensionSchemaNodes)»
172                 «ENDIF»
173                 «IF !module.features.nullOrEmpty»
174
175                 «writeFeatures(module.features)»
176                 «ENDIF»
177                 «IF !module.identities.nullOrEmpty»
178
179                 «writeIdentities(module.identities)»
180                 «ENDIF»
181                 «IF !module.notifications.nullOrEmpty»
182
183                 «writeNotifications(module.notifications)»
184                 «ENDIF»
185                 «IF !module.rpcs.nullOrEmpty»
186
187                 «writeRPCs(module.rpcs)»
188                 «ENDIF»
189                 «IF !module.unknownSchemaNodes.nullOrEmpty»
190
191                 «writeUnknownSchemaNodes(module.unknownSchemaNodes)»
192                 «ENDIF»
193                 «IF !module.uses.nullOrEmpty»
194
195                 «writeUsesNodes(module.uses)»
196                 «ENDIF»
197             }
198         '''
199     }
200
201     def static writeRPCs(Set<RpcDefinition> rpcDefs) {
202         '''
203             «FOR rpc : rpcDefs»
204                 «IF rpc != null»
205                 «writeRPC(rpc)»
206                 «ENDIF»
207             «ENDFOR»
208         '''
209     }
210
211     def static writeRPC(RpcDefinition rpc) {
212         '''
213             rpc «rpc.QName.localName» {
214                 «IF !rpc.description.nullOrEmpty»
215                     "«rpc.description»";
216                 «ENDIF»
217                 «IF !rpc.groupings.nullOrEmpty»
218                     «writeGroupingDefs(rpc.groupings)»
219                 «ENDIF»
220                 «IF rpc.input != null»
221                     «writeRpcInput(rpc.input)»
222                 «ENDIF»
223                 «IF rpc.output != null»
224                     «writeRpcOutput(rpc.output)»
225                 «ENDIF»
226                 «IF !rpc.reference.nullOrEmpty»
227                 reference
228                     "«rpc.reference»";
229                 «ENDIF»
230                 «IF rpc.status != null»
231                 status «rpc.status»;
232                 «ENDIF»
233             }
234         '''
235     }
236
237     def static writeRpcInput(ContainerSchemaNode input) {
238         if(input == null)
239             return ''
240
241         '''
242             input {
243                 «IF input instanceof DataSchemaNode && !input.childNodes.nullOrEmpty»
244                 «writeDataSchemaNodes(input.childNodes)»
245                 «ENDIF»
246             }
247
248         '''
249     }
250
251     def static writeRpcOutput(ContainerSchemaNode output) {
252         if(output == null)
253             return ''
254
255         '''
256             output {
257                 «IF output instanceof DataSchemaNode && !output.childNodes.nullOrEmpty»
258                 «writeDataSchemaNodes(output.childNodes)»
259                 «ENDIF»
260             }
261         '''
262     }
263
264     def static writeNotifications(Set<NotificationDefinition> notifications) {
265         '''
266             «FOR notification : notifications»
267                 «IF notification != null»
268                 «writeNotification(notification)»
269                 «ENDIF»
270             «ENDFOR»
271         '''
272     }
273
274     def static writeNotification(NotificationDefinition notification) {
275         '''
276             notification «notification.QName.localName» {
277                 «IF !notification.description.nullOrEmpty»
278                 description
279                     "«notification.description»";
280                 «ENDIF»
281                 «IF !notification.childNodes.nullOrEmpty»
282                     «writeDataSchemaNodes(notification.childNodes)»
283                 «ENDIF»
284                 «IF !notification.availableAugmentations.nullOrEmpty»
285                     «writeAugments(notification.availableAugmentations)»
286                 «ENDIF»
287                 «IF !notification.groupings.nullOrEmpty»
288                     «writeGroupingDefs(notification.groupings)»
289                 «ENDIF»
290                 «IF !notification.uses.nullOrEmpty»
291                     «writeUsesNodes(notification.uses)»
292                 «ENDIF»
293                 «IF !notification.reference.nullOrEmpty»
294                 reference
295                     "«notification.reference»";
296                 «ENDIF»
297                 «IF notification.status != null»
298                 status «notification.status»;
299                 «ENDIF»
300             }
301         '''
302     }
303
304     def static writeUnknownSchemaNodes(List<UnknownSchemaNode> unknownSchemaNodes) {
305         if (unknownSchemaNodes.nullOrEmpty)
306             return ''
307
308         '''
309             «FOR unknownSchemaNode : unknownSchemaNodes»
310                 «writeUnknownSchemaNode(unknownSchemaNode)»
311             «ENDFOR»
312         '''
313     }
314
315     def static writeUnknownSchemaNode(UnknownSchemaNode unknownSchemaNode) {
316         if (unknownSchemaNode == null)
317             return ''
318
319         '''
320             anyxml «unknownSchemaNode.QName.localName» {
321                 «IF !unknownSchemaNode.description.nullOrEmpty»
322                 description
323                     "«unknownSchemaNode.description»";
324                 «ENDIF»
325                 «IF !unknownSchemaNode.reference.nullOrEmpty»
326                 reference
327                     "«unknownSchemaNode.reference»";
328                 «ENDIF»
329                 «IF unknownSchemaNode.status != null»
330                 status «unknownSchemaNode.status»;
331                 «ENDIF»
332             }
333         '''
334     }
335
336     def static writeUsesNodes(Set<UsesNode> usesNodes) {
337         if (usesNodes == null) {
338             return ''
339         }
340
341         '''
342             «FOR usesNode : usesNodes»
343                 «IF usesNode != null»
344                 «writeUsesNode(usesNode)»
345                 «ENDIF»
346             «ENDFOR»
347         '''
348     }
349
350     def static writeUsesNode(UsesNode usesNode) {
351         val hasRefines = !usesNode.refines.empty
352
353         '''
354             uses «usesNode.groupingPath.pathFromRoot.head.localName»«IF !hasRefines»;«ELSE» {«ENDIF»
355             «IF hasRefines»
356                 «writeRefines(usesNode.refines)»
357             }
358             «ENDIF»
359         '''
360     }
361
362     def static writeRefines(Map<SchemaPath, SchemaNode> refines) {
363         '''
364             «FOR path : refines.keySet»
365             «val schemaNode = refines.get(path)»
366             «writeRefine(path, schemaNode)»
367             «ENDFOR»
368         '''
369     }
370
371     def static writeRefine(SchemaPath path, SchemaNode schemaNode) {
372         '''
373             refine «path.pathFromRoot.last» {
374                 «IF schemaNode instanceof DataSchemaNode»
375                 «writeDataSchemaNode(schemaNode as DataSchemaNode)»
376                 «ENDIF»
377             }
378         '''
379     }
380
381     def static writeTypeDefinitions(Set<TypeDefinition<?>> typeDefinitions) {
382         '''
383             «FOR typeDefinition : typeDefinitions»
384                 «IF typeDefinition != null»
385                 «writeTypeDefinition(typeDefinition)»
386                 «ENDIF»
387             «ENDFOR»
388         '''
389     }
390
391     def static writeTypeDefinition(TypeDefinition<?> typeDefinition) {
392         '''
393             type «typeDefinition.QName.localName»;
394         '''
395     }
396
397     def static writeIdentities(Set<IdentitySchemaNode> identities) {
398         if (identities.nullOrEmpty)
399             return ''
400         '''
401             «FOR identity : identities»
402                 «writeIdentity(identity)»
403             «ENDFOR»
404         '''
405     }
406
407     def static writeIdentity(IdentitySchemaNode identity) {
408         if (identity == null)
409             return ''
410         '''
411             identity «identity.QName.localName» {
412                 «IF identity.baseIdentity != null»
413                 base "(«writeIdentityNs(identity.baseIdentity)»)«identity.baseIdentity»";
414                 «ENDIF»
415                 «IF !identity.description.nullOrEmpty»
416                 description
417                     "«identity.description»";
418                 «ENDIF»
419                 «IF !identity.reference.nullOrEmpty»
420                 reference
421                     "«identity.reference»";
422                 «ENDIF»
423                 «IF identity.status != null»
424                 status «identity.status»;
425                 «ENDIF»
426             }
427         '''
428     }
429
430     def static writeIdentityNs(IdentitySchemaNode identity) {
431         if(module == null)
432             return ''
433
434         val identityNs = identity.QName.namespace
435
436         if(!module.namespace.equals(identityNs))
437             return identityNs + ":"
438         return ''
439     }
440
441     def static writeFeatures(Set<FeatureDefinition> features) {
442         '''
443             «FOR feature : features»
444                 «IF feature != null»
445                 «writeFeature(feature)»
446                 «ENDIF»
447             «ENDFOR»
448         '''
449     }
450
451     def static writeFeature(FeatureDefinition featureDef) {
452         '''
453             feature «featureDef.QName.localName» {
454                 «IF !featureDef.description.nullOrEmpty»
455                 description
456                     "«featureDef.description»";
457                 «ENDIF»
458                 «IF !featureDef.reference.nullOrEmpty»
459                 reference
460                     "«featureDef.reference»";
461                 «ENDIF»
462                 «IF featureDef.status != null»
463                 status «featureDef.status»;
464                 «ENDIF»
465             }
466         '''
467     }
468
469     def static writeExtensions(List<ExtensionDefinition> extensions) {
470         '''
471             «FOR anExtension : extensions»
472                 «IF anExtension != null»
473                 «writeExtension(anExtension)»
474                 «ENDIF»
475             «ENDFOR»
476         '''
477     }
478
479     def static writeExtension(ExtensionDefinition extensionDef) {
480         '''
481             extension «extensionDef.QName.localName» {
482                 «IF !extensionDef.description.nullOrEmpty»
483                 description
484                     "«extensionDef.description»";
485                 «ENDIF»
486                 «IF !extensionDef.argument.nullOrEmpty»
487                 argument "«extensionDef.argument»";
488                 «ENDIF»
489                 «IF !extensionDef.reference.nullOrEmpty»
490                 reference
491                     "«extensionDef.reference»";
492                 «ENDIF»
493                 «IF extensionDef.status != null»
494                 status «extensionDef.status»;
495                 «ENDIF»
496             }
497         '''
498     }
499
500     def static writeDeviations(Set<Deviation> deviations) {
501         '''
502             «FOR deviation : deviations»
503                 «IF deviation != null»
504                 «writeDeviation(deviation)»
505                 «ENDIF»
506             «ENDFOR»
507         '''
508     }
509
510     def static writeDeviation(Deviation deviation) {
511         '''
512             deviation «deviation.targetPath» {
513                 «IF !deviation.reference.nullOrEmpty»
514                     reference
515                         "«deviation.reference»";
516                 «ENDIF»
517                 «IF deviation.deviate != null && !deviation.deviate.name.nullOrEmpty»
518                     deviation «deviation.deviate.name»;
519                 «ENDIF»
520             }
521         '''
522     }
523
524     def static writeAugments(Set<AugmentationSchema> augments) {
525         '''
526             «FOR augment : augments»
527                 «IF augment != null»
528                 «writeAugment(augment)»
529                 «ENDIF»
530             «ENDFOR»
531         '''
532     }
533
534     def static writeDataSchemaNodes(Collection<DataSchemaNode> dataSchemaNodes) {
535         '''
536             «FOR schemaNode : dataSchemaNodes»
537                 «writeDataSchemaNode(schemaNode)»
538             «ENDFOR»
539         '''
540     }
541
542     def static CharSequence writeGroupingDefs(Set<GroupingDefinition> groupingDefs) {
543         '''
544             «FOR groupingDef : groupingDefs»
545                 «IF groupingDef != null»
546                 «writeGroupingDef(groupingDef)»
547                 «ENDIF»
548             «ENDFOR»
549         '''
550     }
551
552     def static writeAugment(AugmentationSchema augment) {
553         '''
554             augment «formatToAugmentPath(augment.targetPath.pathFromRoot)» {
555                 «IF augment.whenCondition != null && !augment.whenCondition.toString.nullOrEmpty»
556                 when "«augment.whenCondition.toString»";
557                 «ENDIF»
558                 «IF !augment.description.nullOrEmpty»
559                 description
560                     "«augment.description»";
561                 «ENDIF»
562                 «IF !augment.reference.nullOrEmpty»
563                 reference
564                     "«augment.reference»";
565                 «ENDIF»
566                 «IF augment.status != null»
567                 status «augment.status»;
568                 «ENDIF»
569                 «IF !augment.childNodes.nullOrEmpty»
570                 «writeDataSchemaNodes(augment.childNodes)»
571                 «ENDIF»
572                 «IF !augment.uses.nullOrEmpty»
573                 «writeUsesNodes(augment.uses)»
574                 «ENDIF»
575             }
576         '''
577     }
578
579     def static writeGroupingDef(GroupingDefinition groupingDef) {
580         '''
581             grouping «groupingDef.QName.localName» {
582                 «IF !groupingDef.groupings.nullOrEmpty»
583                     «writeGroupingDefs(groupingDef.groupings)»
584                 «ENDIF»
585                 «IF !groupingDef.childNodes.nullOrEmpty»
586                     «writeDataSchemaNodes(groupingDef.childNodes)»
587                 «ENDIF»
588                 «IF !groupingDef.unknownSchemaNodes.nullOrEmpty»
589                     «writeUnknownSchemaNodes(groupingDef.unknownSchemaNodes)»
590                 «ENDIF»
591             }
592         '''
593     }
594
595     def static writeContSchemaNode(ContainerSchemaNode contSchemaNode) {
596         '''
597             container «contSchemaNode.getQName.localName» {
598                 «IF !contSchemaNode.childNodes.nullOrEmpty»
599                 «writeDataSchemaNodes(contSchemaNode.childNodes)»
600                 «ENDIF»
601                 «IF !contSchemaNode.availableAugmentations.nullOrEmpty»
602                 «writeAugments(contSchemaNode.availableAugmentations)»
603                 «ENDIF»
604                 «IF !contSchemaNode.groupings.nullOrEmpty»
605                 «writeGroupingDefs(contSchemaNode.groupings)»
606                 «ENDIF»
607                 «IF !contSchemaNode.uses.nullOrEmpty»
608                 «writeUsesNodes(contSchemaNode.uses)»
609                 «ENDIF»
610                 «IF !contSchemaNode.unknownSchemaNodes.nullOrEmpty»
611                 «writeUnknownSchemaNodes(contSchemaNode.unknownSchemaNodes)»
612                 «ENDIF»
613             }
614         '''
615     }
616
617     def static writeAnyXmlSchemaNode(AnyXmlSchemaNode anyXmlSchemaNode) {
618         '''
619             anyxml «anyXmlSchemaNode.getQName.localName»;
620         '''
621     }
622
623     def static writeLeafSchemaNode(LeafSchemaNode leafSchemaNode) {
624         '''
625             leaf «leafSchemaNode.getQName.localName» {
626                 type «leafSchemaNode.type.getQName.localName»;
627             }
628         '''
629     }
630
631     def static writeLeafListSchemaNode(LeafListSchemaNode leafListSchemaNode) {
632         '''
633             leaf-list «leafListSchemaNode.getQName.localName» {
634                 type «leafListSchemaNode.type.getQName.localName»;
635             }
636         '''
637     }
638
639     def static writeChoiceCaseNode(ChoiceCaseNode choiceCaseNode) {
640         '''
641             case «choiceCaseNode.getQName.localName» {
642                 «FOR childNode : choiceCaseNode.childNodes»
643                     «writeDataSchemaNode(childNode)»
644                 «ENDFOR»
645             }
646         '''
647     }
648
649     def static writeChoiceNode(ChoiceNode choiceNode) {
650         '''
651             choice «choiceNode.getQName.localName» {
652                 «FOR child : choiceNode.cases»
653                     «writeDataSchemaNode(child)»
654                 «ENDFOR»
655             }
656         '''
657     }
658
659     def static writeListSchemaNode(ListSchemaNode listSchemaNode) {
660         '''
661             list «listSchemaNode.getQName.localName» {
662                 key «FOR listKey : listSchemaNode.keyDefinition SEPARATOR " "»"«listKey.localName»"
663                 «ENDFOR»
664                 «IF !listSchemaNode.childNodes.nullOrEmpty»
665                     «writeDataSchemaNodes(listSchemaNode.childNodes)»
666                 «ENDIF»
667                 «IF !listSchemaNode.availableAugmentations.nullOrEmpty»
668                     «writeAugments(listSchemaNode.availableAugmentations)»
669                 «ENDIF»
670                 «IF !listSchemaNode.groupings.nullOrEmpty»
671                     «writeGroupingDefs(listSchemaNode.groupings)»
672                 «ENDIF»
673                 «IF !listSchemaNode.uses.nullOrEmpty»
674                     «writeUsesNodes(listSchemaNode.uses)»
675                 «ENDIF»
676                 «IF !listSchemaNode.unknownSchemaNodes.nullOrEmpty»
677                     «writeUnknownSchemaNodes(listSchemaNode.unknownSchemaNodes)»
678                 «ENDIF»
679             }
680         '''
681     }
682
683     def static CharSequence writeDataSchemaNode(DataSchemaNode child) {
684         '''
685             «IF child instanceof ContainerSchemaNode»
686                 «writeContSchemaNode(child as ContainerSchemaNode)»
687             «ENDIF»
688             «IF child instanceof AnyXmlSchemaNode»
689                 «writeAnyXmlSchemaNode(child as AnyXmlSchemaNode)»
690             «ENDIF»
691             «IF child instanceof LeafSchemaNode»
692                 «writeLeafSchemaNode(child as LeafSchemaNode)»
693             «ENDIF»
694             «IF child instanceof LeafListSchemaNode»
695                 «writeLeafListSchemaNode(child as LeafListSchemaNode)»
696             «ENDIF»
697             «IF child instanceof ChoiceCaseNode»
698                 «writeChoiceCaseNode(child as ChoiceCaseNode)»
699             «ENDIF»
700             «IF child instanceof ChoiceNode»
701                 «writeChoiceNode(child as ChoiceNode)»
702             «ENDIF»
703             «IF child instanceof ListSchemaNode»
704                 «writeListSchemaNode(child as ListSchemaNode)»
705             «ENDIF»
706         '''
707     }
708     
709     static def String formatSchemaPath(String moduleName, Iterable<QName> schemaPath) {
710         var currentElement = schemaPath.head
711         val StringBuilder sb = new StringBuilder()
712         sb.append(moduleName)
713
714         for(pathElement : schemaPath) {
715             if(!currentElement.namespace.equals(pathElement.namespace)) {
716                 currentElement = pathElement
717                 sb.append('/')
718                 sb.append(pathElement)
719             }
720             else {
721                 sb.append('/')
722                 sb.append(pathElement.localName)
723             }
724         }
725         return sb.toString
726     }
727
728     static def String formatToParagraph(String text, int nextLineIndent) {
729         if (text == null || text.isEmpty())
730             return '';
731
732         var String formattedText = text;
733         val StringBuilder sb = new StringBuilder();
734         val StringBuilder lineBuilder = new StringBuilder();
735         var boolean isFirstElementOnNewLineEmptyChar = false;
736         val lineIndent = computeNextLineIndent(nextLineIndent);
737
738         formattedText = formattedText.replace("*/", "&#42;&#47;");
739         formattedText = formattedText.replace("\n", "");
740         formattedText = formattedText.replace("\t", "");
741         formattedText = formattedText.replaceAll(" +", " ");
742
743         val StringTokenizer tokenizer = new StringTokenizer(formattedText, " ", true);
744
745         while (tokenizer.hasMoreElements()) {
746             val String nextElement = tokenizer.nextElement().toString();
747
748             if (lineBuilder.length() + nextElement.length() > 80) {
749                 if (lineBuilder.charAt(lineBuilder.length() - 1) == ' ') {
750                     lineBuilder.setLength(0);
751                     lineBuilder.append(lineBuilder.substring(0, lineBuilder.length() - 1));
752                 }
753                 if (lineBuilder.charAt(0) == ' ') {
754                     lineBuilder.setLength(0);
755                     lineBuilder.append(lineBuilder.substring(1));
756                 }
757
758                 sb.append(lineBuilder);
759                 lineBuilder.setLength(0);
760                 sb.append("\n");
761
762                 if (nextLineIndent > 0) {
763                     sb.append(lineIndent)
764                 }
765
766                 if (nextElement.toString().equals(" "))
767                     isFirstElementOnNewLineEmptyChar = !isFirstElementOnNewLineEmptyChar;
768             }
769             if (isFirstElementOnNewLineEmptyChar) {
770                 isFirstElementOnNewLineEmptyChar = !isFirstElementOnNewLineEmptyChar;
771             } else {
772                 lineBuilder.append(nextElement);
773             }
774         }
775         sb.append(lineBuilder);
776         sb.append("\n");
777
778         return sb.toString();
779     }
780
781     def private static formatToAugmentPath(Iterable<QName> schemaPath) {
782         val StringBuilder sb = new StringBuilder();
783
784         for(pathElement : schemaPath) {
785             val ns = pathElement.namespace
786             val localName = pathElement.localName
787
788             sb.append("\\")
789             sb.append('(')
790             sb.append(ns)
791             sb.append(')')
792             sb.append(localName)
793         }
794         return sb.toString
795     }
796
797     private static def computeNextLineIndent(int nextLineIndent) {
798         val StringBuilder sb = new StringBuilder()
799         var i = 0
800         while (i < nextLineIndent) {
801             sb.append(' ')
802             i = i + 1
803         }
804         return sb.toString
805     }
806 }