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