396001dbd31d95fd343f73cb47e0367f37b5cc5c
[yangtools.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 "«writeIdentityPrefix(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 writeIdentityPrefix(IdentitySchemaNode identity) {
431         if(module == null)
432             return ''
433
434         if(identity.QName.prefix.nullOrEmpty || module.prefix.nullOrEmpty)
435             return ''
436
437         val identityPrefix = identity.QName.prefix
438
439         if(!module.prefix.equals(identity.QName.prefix))
440             return identityPrefix + ":"
441         return ''
442     }
443
444     def static writeFeatures(Set<FeatureDefinition> features) {
445         '''
446             «FOR feature : features»
447                 «IF feature != null»
448                 «writeFeature(feature)»
449                 «ENDIF»
450             «ENDFOR»
451         '''
452     }
453
454     def static writeFeature(FeatureDefinition featureDef) {
455         '''
456             feature «featureDef.QName.localName» {
457                 «IF !featureDef.description.nullOrEmpty»
458                 description
459                     "«featureDef.description»";
460                 «ENDIF»
461                 «IF !featureDef.reference.nullOrEmpty»
462                 reference
463                     "«featureDef.reference»";
464                 «ENDIF»
465                 «IF featureDef.status != null»
466                 status «featureDef.status»;
467                 «ENDIF»
468             }
469         '''
470     }
471
472     def static writeExtensions(List<ExtensionDefinition> extensions) {
473         '''
474             «FOR anExtension : extensions»
475                 «IF anExtension != null»
476                 «writeExtension(anExtension)»
477                 «ENDIF»
478             «ENDFOR»
479         '''
480     }
481
482     def static writeExtension(ExtensionDefinition extensionDef) {
483         '''
484             extension «extensionDef.QName.localName» {
485                 «IF !extensionDef.description.nullOrEmpty»
486                 description
487                     "«extensionDef.description»";
488                 «ENDIF»
489                 «IF !extensionDef.argument.nullOrEmpty»
490                 argument "«extensionDef.argument»";
491                 «ENDIF»
492                 «IF !extensionDef.reference.nullOrEmpty»
493                 reference
494                     "«extensionDef.reference»";
495                 «ENDIF»
496                 «IF extensionDef.status != null»
497                 status «extensionDef.status»;
498                 «ENDIF»
499             }
500         '''
501     }
502
503     def static writeDeviations(Set<Deviation> deviations) {
504         '''
505             «FOR deviation : deviations»
506                 «IF deviation != null»
507                 «writeDeviation(deviation)»
508                 «ENDIF»
509             «ENDFOR»
510         '''
511     }
512
513     def static writeDeviation(Deviation deviation) {
514         '''
515             deviation «deviation.targetPath» {
516                 «IF !deviation.reference.nullOrEmpty»
517                     reference
518                         "«deviation.reference»";
519                 «ENDIF»
520                 «IF deviation.deviate != null && !deviation.deviate.name.nullOrEmpty»
521                     deviation «deviation.deviate.name»;
522                 «ENDIF»
523             }
524         '''
525     }
526
527     def static writeAugments(Set<AugmentationSchema> augments) {
528         '''
529             «FOR augment : augments»
530                 «IF augment != null»
531                 «writeAugment(augment)»
532                 «ENDIF»
533             «ENDFOR»
534         '''
535     }
536
537     def static writeDataSchemaNodes(Collection<DataSchemaNode> dataSchemaNodes) {
538         '''
539             «FOR schemaNode : dataSchemaNodes»
540                 «writeDataSchemaNode(schemaNode)»
541             «ENDFOR»
542         '''
543     }
544
545     def static CharSequence writeGroupingDefs(Set<GroupingDefinition> groupingDefs) {
546         '''
547             «FOR groupingDef : groupingDefs»
548                 «IF groupingDef != null»
549                 «writeGroupingDef(groupingDef)»
550                 «ENDIF»
551             «ENDFOR»
552         '''
553     }
554
555     def static writeAugment(AugmentationSchema augment) {
556         '''
557             augment «formatToAugmentPath(augment.targetPath.pathFromRoot)» {
558                 «IF augment.whenCondition != null && !augment.whenCondition.toString.nullOrEmpty»
559                 when "«augment.whenCondition.toString»";
560                 «ENDIF»
561                 «IF !augment.description.nullOrEmpty»
562                 description
563                     "«augment.description»";
564                 «ENDIF»
565                 «IF !augment.reference.nullOrEmpty»
566                 reference
567                     "«augment.reference»";
568                 «ENDIF»
569                 «IF augment.status != null»
570                 status «augment.status»;
571                 «ENDIF»
572                 «IF !augment.childNodes.nullOrEmpty»
573                 «writeDataSchemaNodes(augment.childNodes)»
574                 «ENDIF»
575                 «IF !augment.uses.nullOrEmpty»
576                 «writeUsesNodes(augment.uses)»
577                 «ENDIF»
578             }
579         '''
580     }
581
582     def static writeGroupingDef(GroupingDefinition groupingDef) {
583         '''
584             grouping «groupingDef.QName.localName» {
585                 «IF !groupingDef.groupings.nullOrEmpty»
586                     «writeGroupingDefs(groupingDef.groupings)»
587                 «ENDIF»
588                 «IF !groupingDef.childNodes.nullOrEmpty»
589                     «writeDataSchemaNodes(groupingDef.childNodes)»
590                 «ENDIF»
591                 «IF !groupingDef.unknownSchemaNodes.nullOrEmpty»
592                     «writeUnknownSchemaNodes(groupingDef.unknownSchemaNodes)»
593                 «ENDIF»
594             }
595         '''
596     }
597
598     def static writeContSchemaNode(ContainerSchemaNode contSchemaNode) {
599         '''
600             container «contSchemaNode.getQName.localName» {
601                 «IF !contSchemaNode.childNodes.nullOrEmpty»
602                 «writeDataSchemaNodes(contSchemaNode.childNodes)»
603                 «ENDIF»
604                 «IF !contSchemaNode.availableAugmentations.nullOrEmpty»
605                 «writeAugments(contSchemaNode.availableAugmentations)»
606                 «ENDIF»
607                 «IF !contSchemaNode.groupings.nullOrEmpty»
608                 «writeGroupingDefs(contSchemaNode.groupings)»
609                 «ENDIF»
610                 «IF !contSchemaNode.uses.nullOrEmpty»
611                 «writeUsesNodes(contSchemaNode.uses)»
612                 «ENDIF»
613                 «IF !contSchemaNode.unknownSchemaNodes.nullOrEmpty»
614                 «writeUnknownSchemaNodes(contSchemaNode.unknownSchemaNodes)»
615                 «ENDIF»
616             }
617         '''
618     }
619
620     def static writeAnyXmlSchemaNode(AnyXmlSchemaNode anyXmlSchemaNode) {
621         '''
622             anyxml «anyXmlSchemaNode.getQName.localName»;
623         '''
624     }
625
626     def static writeLeafSchemaNode(LeafSchemaNode leafSchemaNode) {
627         '''
628             leaf «leafSchemaNode.getQName.localName» {
629                 type «leafSchemaNode.type.getQName.localName»;
630             }
631         '''
632     }
633
634     def static writeLeafListSchemaNode(LeafListSchemaNode leafListSchemaNode) {
635         '''
636             leaf-list «leafListSchemaNode.getQName.localName» {
637                 type «leafListSchemaNode.type.getQName.localName»;
638             }
639         '''
640     }
641
642     def static writeChoiceCaseNode(ChoiceCaseNode choiceCaseNode) {
643         '''
644             case «choiceCaseNode.getQName.localName» {
645                 «FOR childNode : choiceCaseNode.childNodes»
646                     «writeDataSchemaNode(childNode)»
647                 «ENDFOR»
648             }
649         '''
650     }
651
652     def static writeChoiceNode(ChoiceNode choiceNode) {
653         '''
654             choice «choiceNode.getQName.localName» {
655                 «FOR child : choiceNode.cases»
656                     «writeDataSchemaNode(child)»
657                 «ENDFOR»
658             }
659         '''
660     }
661
662     def static writeListSchemaNode(ListSchemaNode listSchemaNode) {
663         '''
664             list «listSchemaNode.getQName.localName» {
665                 key «FOR listKey : listSchemaNode.keyDefinition SEPARATOR " "»"«listKey.localName»"
666                 «ENDFOR»
667                 «IF !listSchemaNode.childNodes.nullOrEmpty»
668                     «writeDataSchemaNodes(listSchemaNode.childNodes)»
669                 «ENDIF»
670                 «IF !listSchemaNode.availableAugmentations.nullOrEmpty»
671                     «writeAugments(listSchemaNode.availableAugmentations)»
672                 «ENDIF»
673                 «IF !listSchemaNode.groupings.nullOrEmpty»
674                     «writeGroupingDefs(listSchemaNode.groupings)»
675                 «ENDIF»
676                 «IF !listSchemaNode.uses.nullOrEmpty»
677                     «writeUsesNodes(listSchemaNode.uses)»
678                 «ENDIF»
679                 «IF !listSchemaNode.unknownSchemaNodes.nullOrEmpty»
680                     «writeUnknownSchemaNodes(listSchemaNode.unknownSchemaNodes)»
681                 «ENDIF»
682             }
683         '''
684     }
685
686     def static CharSequence writeDataSchemaNode(DataSchemaNode child) {
687         '''
688             «IF child instanceof ContainerSchemaNode»
689                 «writeContSchemaNode(child as ContainerSchemaNode)»
690             «ENDIF»
691             «IF child instanceof AnyXmlSchemaNode»
692                 «writeAnyXmlSchemaNode(child as AnyXmlSchemaNode)»
693             «ENDIF»
694             «IF child instanceof LeafSchemaNode»
695                 «writeLeafSchemaNode(child as LeafSchemaNode)»
696             «ENDIF»
697             «IF child instanceof LeafListSchemaNode»
698                 «writeLeafListSchemaNode(child as LeafListSchemaNode)»
699             «ENDIF»
700             «IF child instanceof ChoiceCaseNode»
701                 «writeChoiceCaseNode(child as ChoiceCaseNode)»
702             «ENDIF»
703             «IF child instanceof ChoiceNode»
704                 «writeChoiceNode(child as ChoiceNode)»
705             «ENDIF»
706             «IF child instanceof ListSchemaNode»
707                 «writeListSchemaNode(child as ListSchemaNode)»
708             «ENDIF»
709         '''
710     }
711     
712     static def String formatSchemaPath(String moduleName, Iterable<QName> schemaPath) {
713         var currentElement = schemaPath.head
714         val StringBuilder sb = new StringBuilder()
715         sb.append(moduleName)
716
717         for(pathElement : schemaPath) {
718             if(!currentElement.namespace.equals(pathElement.namespace)) {
719                 currentElement = pathElement
720                 sb.append('/')
721                 sb.append(pathElement)
722             }
723             else {
724                 sb.append('/')
725                 sb.append(pathElement.localName)
726             }
727         }
728         return sb.toString
729     }
730
731     static def String formatToParagraph(String text, int nextLineIndent) {
732         if (text == null || text.isEmpty())
733             return '';
734
735         var String formattedText = text;
736         val StringBuilder sb = new StringBuilder();
737         val StringBuilder lineBuilder = new StringBuilder();
738         var boolean isFirstElementOnNewLineEmptyChar = false;
739         val lineIndent = computeNextLineIndent(nextLineIndent);
740
741         formattedText = formattedText.replace("*/", "&#42;&#47;");
742         formattedText = formattedText.replace("\n", "");
743         formattedText = formattedText.replace("\t", "");
744         formattedText = formattedText.replaceAll(" +", " ");
745
746         val StringTokenizer tokenizer = new StringTokenizer(formattedText, " ", true);
747
748         while (tokenizer.hasMoreElements()) {
749             val String nextElement = tokenizer.nextElement().toString();
750
751             if (lineBuilder.length() + nextElement.length() > 80) {
752                 if (lineBuilder.charAt(lineBuilder.length() - 1) == ' ') {
753                     lineBuilder.setLength(0);
754                     lineBuilder.append(lineBuilder.substring(0, lineBuilder.length() - 1));
755                 }
756                 if (lineBuilder.charAt(0) == ' ') {
757                     lineBuilder.setLength(0);
758                     lineBuilder.append(lineBuilder.substring(1));
759                 }
760
761                 sb.append(lineBuilder);
762                 lineBuilder.setLength(0);
763                 sb.append("\n");
764
765                 if (nextLineIndent > 0) {
766                     sb.append(lineIndent)
767                 }
768
769                 if (nextElement.toString().equals(" "))
770                     isFirstElementOnNewLineEmptyChar = !isFirstElementOnNewLineEmptyChar;
771             }
772             if (isFirstElementOnNewLineEmptyChar) {
773                 isFirstElementOnNewLineEmptyChar = !isFirstElementOnNewLineEmptyChar;
774             } else {
775                 lineBuilder.append(nextElement);
776             }
777         }
778         sb.append(lineBuilder);
779         sb.append("\n");
780
781         return sb.toString();
782     }
783
784     def private static formatToAugmentPath(Iterable<QName> schemaPath) {
785         val StringBuilder sb = new StringBuilder();
786
787         for(pathElement : schemaPath) {
788             val prefix = pathElement.prefix
789             val localName = pathElement.localName
790
791             sb.append("\\")
792             sb.append(prefix)
793             sb.append(":")
794             sb.append(localName)
795         }
796         return sb.toString
797     }
798
799     private static def computeNextLineIndent(int nextLineIndent) {
800         val StringBuilder sb = new StringBuilder()
801         var i = 0
802         while (i < nextLineIndent) {
803             sb.append(' ')
804             i = i + 1
805         }
806         return sb.toString
807     }
808 }