2 * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
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
8 package org.opendaylight.yangtools.sal.binding.generator.impl
10 import java.util.Collection
15 import org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil
16 import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode
17 import org.opendaylight.yangtools.yang.model.api.AugmentationSchema
18 import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode
19 import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode
20 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode
21 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode
22 import org.opendaylight.yangtools.yang.model.api.Deviation
23 import org.opendaylight.yangtools.yang.model.api.ExtensionDefinition
24 import org.opendaylight.yangtools.yang.model.api.FeatureDefinition
25 import org.opendaylight.yangtools.yang.model.api.GroupingDefinition
26 import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode
27 import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode
28 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode
29 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode
30 import org.opendaylight.yangtools.yang.model.api.Module
31 import org.opendaylight.yangtools.yang.model.api.ModuleImport
32 import org.opendaylight.yangtools.yang.model.api.NotificationDefinition
33 import org.opendaylight.yangtools.yang.model.api.RpcDefinition
34 import org.opendaylight.yangtools.yang.model.api.SchemaNode
35 import org.opendaylight.yangtools.yang.model.api.SchemaPath
36 import org.opendaylight.yangtools.yang.model.api.Status
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
45 // FIXME: this is not thread-safe and seems to be unused!
46 private static var Module module = null
48 def static String generateYangSnipet(SchemaNode schemaNode) {
49 if (schemaNode == null)
53 «IF schemaNode instanceof DataSchemaNode»
54 «writeDataSchemaNode(schemaNode)»
56 «IF schemaNode instanceof EnumTypeDefinition.EnumPair»
57 «writeEnumPair(schemaNode)»
59 «IF schemaNode instanceof ExtensionDefinition»
60 «writeExtension(schemaNode)»
62 «IF schemaNode instanceof FeatureDefinition»
63 «writeFeature(schemaNode)»
65 «IF schemaNode instanceof GroupingDefinition»
66 «writeGroupingDef(schemaNode)»
68 «IF schemaNode instanceof IdentitySchemaNode»
69 «writeIdentity(schemaNode)»
71 «IF schemaNode instanceof NotificationDefinition»
72 «writeNotification(schemaNode)»
74 «IF schemaNode instanceof RpcDefinition»
75 «writeRPC(schemaNode)»
77 «IF schemaNode instanceof TypeDefinition<?>»
78 «writeTypeDefinition(schemaNode)»
80 «IF schemaNode instanceof UnknownSchemaNode»
81 «writeUnknownSchemaNode(schemaNode)»
86 def static String generateYangSnipet(Set<? extends SchemaNode> nodes) {
87 if (nodes.nullOrEmpty)
92 «IF node instanceof NotificationDefinition»
93 «writeNotification(node)»
94 «ELSEIF node instanceof RpcDefinition»
95 «writeRPC(node as RpcDefinition)»
101 def private static writeEnumPair(EnumPair pair) {
109 def private static String writeModuleImports(Set<ModuleImport> moduleImports) {
110 if (moduleImports.nullOrEmpty)
114 «FOR moduleImport : moduleImports SEPARATOR "\n"»
115 «IF moduleImport != null && !moduleImport.moduleName.nullOrEmpty»
116 import «moduleImport.moduleName» { prefix "«moduleImport.prefix»"; }
122 def private static writeRevision(Date moduleRevision, String moduleDescription) {
123 val revisionIndent = 12
126 revision «SimpleDateFormatUtil.getRevisionFormat.format(moduleRevision)» {
127 description "«YangTextTemplate.formatToParagraph(moduleDescription, revisionIndent)»";
132 def static String generateYangSnipet(Module module) {
135 module «module.name» {
136 yang-version «module.yangVersion»;
137 namespace "«module.QNameModule.namespace.toString»";
138 prefix "«module.prefix»";
140 «IF !module.imports.nullOrEmpty»
141 «writeModuleImports(module.imports)»
143 «IF module.revision != null»
144 «writeRevision(module.revision, module.description)»
146 «IF !module.childNodes.nullOrEmpty»
148 «writeDataSchemaNodes(module.childNodes)»
150 «IF !module.groupings.nullOrEmpty»
152 «writeGroupingDefs(module.groupings)»
154 «IF !module.augmentations.nullOrEmpty»
156 «writeAugments(module.augmentations)»
158 «IF !module.deviations.nullOrEmpty»
160 «writeDeviations(module.deviations)»
162 «IF !module.extensionSchemaNodes.nullOrEmpty»
164 «writeExtensions(module.extensionSchemaNodes)»
166 «IF !module.features.nullOrEmpty»
168 «writeFeatures(module.features)»
170 «IF !module.identities.nullOrEmpty»
172 «writeIdentities(module.identities)»
174 «IF !module.notifications.nullOrEmpty»
176 «writeNotifications(module.notifications)»
178 «IF !module.rpcs.nullOrEmpty»
180 «writeRPCs(module.rpcs)»
182 «IF !module.unknownSchemaNodes.nullOrEmpty»
184 «writeUnknownSchemaNodes(module.unknownSchemaNodes)»
186 «IF !module.uses.nullOrEmpty»
188 «writeUsesNodes(module.uses)»
194 def private static writeRPCs(Set<RpcDefinition> rpcDefs) {
204 def private static writeRPC(RpcDefinition rpc) {
205 var boolean isStatusDeprecated = rpc.status == Status::DEPRECATED
207 rpc «rpc.QName.localName» {
208 «IF !rpc.description.nullOrEmpty»
211 «IF !rpc.groupings.nullOrEmpty»
212 «writeGroupingDefs(rpc.groupings)»
214 «IF rpc.input != null»
215 «writeRpcInput(rpc.input)»
217 «IF rpc.output != null»
218 «writeRpcOutput(rpc.output)»
220 «IF !rpc.reference.nullOrEmpty»
224 «IF isStatusDeprecated»
231 def private static writeRpcInput(ContainerSchemaNode input) {
237 «IF !input.childNodes.nullOrEmpty»
238 «writeDataSchemaNodes(input.childNodes)»
245 def private static writeRpcOutput(ContainerSchemaNode output) {
251 «IF !output.childNodes.nullOrEmpty»
252 «writeDataSchemaNodes(output.childNodes)»
258 def private static writeNotifications(Set<NotificationDefinition> notifications) {
260 «FOR notification : notifications»
261 «IF notification != null»
262 «writeNotification(notification)»
268 def private static writeNotification(NotificationDefinition notification) {
269 var boolean isStatusDeprecated = notification.status == Status::DEPRECATED
271 notification «notification.QName.localName» {
272 «IF !notification.description.nullOrEmpty»
274 "«notification.description»";
276 «IF !notification.childNodes.nullOrEmpty»
277 «writeDataSchemaNodes(notification.childNodes)»
279 «IF !notification.availableAugmentations.nullOrEmpty»
280 «writeAugments(notification.availableAugmentations)»
282 «IF !notification.groupings.nullOrEmpty»
283 «writeGroupingDefs(notification.groupings)»
285 «IF !notification.uses.nullOrEmpty»
286 «writeUsesNodes(notification.uses)»
288 «IF !notification.reference.nullOrEmpty»
290 "«notification.reference»";
292 «IF isStatusDeprecated»
293 status «notification.status»;
299 def private static writeUnknownSchemaNodes(List<UnknownSchemaNode> unknownSchemaNodes) {
300 if (unknownSchemaNodes.nullOrEmpty)
304 «FOR unknownSchemaNode : unknownSchemaNodes»
305 «writeUnknownSchemaNode(unknownSchemaNode)»
310 def private static writeUnknownSchemaNode(UnknownSchemaNode unknownSchemaNode) {
314 def private static writeUsesNodes(Set<UsesNode> usesNodes) {
315 if (usesNodes == null) {
320 «FOR usesNode : usesNodes»
321 «IF usesNode != null»
322 «writeUsesNode(usesNode)»
328 def private static writeUsesNode(UsesNode usesNode) {
329 val hasRefines = !usesNode.refines.empty
332 uses «usesNode.groupingPath.pathFromRoot.head.localName»«IF !hasRefines»;«ELSE» {«ENDIF»
334 «writeRefines(usesNode.refines)»
340 def private static writeRefines(Map<SchemaPath, SchemaNode> refines) {
342 «FOR path : refines.keySet»
343 «val schemaNode = refines.get(path)»
344 «writeRefine(path, schemaNode)»
349 def private static writeRefine(SchemaPath path, SchemaNode schemaNode) {
351 refine «path.pathFromRoot.last» {
352 «IF schemaNode instanceof DataSchemaNode»
353 «writeDataSchemaNode(schemaNode)»
359 def private static writeTypeDefinition(TypeDefinition<?> typeDefinition) {
360 var boolean isStatusDeprecated = typeDefinition.status == Status::DEPRECATED
362 type «typeDefinition.QName.localName»«IF !isStatusDeprecated»;«ELSE» {
363 status «typeDefinition.status»;
369 def private static writeIdentities(Set<IdentitySchemaNode> identities) {
370 if (identities.nullOrEmpty)
373 «FOR identity : identities»
374 «writeIdentity(identity)»
379 def private static writeIdentity(IdentitySchemaNode identity) {
380 if (identity == null)
383 identity «identity.QName.localName» {
384 «IF identity.baseIdentity != null»
385 base "(«writeIdentityNs(identity.baseIdentity)»)«identity.baseIdentity»";
387 «IF !identity.description.nullOrEmpty»
389 "«identity.description»";
391 «IF !identity.reference.nullOrEmpty»
393 "«identity.reference»";
395 «IF identity.status != null»
396 status «identity.status»;
402 def private static writeIdentityNs(IdentitySchemaNode identity) {
406 val identityNs = identity.QName.namespace
408 if(!module.namespace.equals(identityNs))
409 return identityNs + ":"
413 def private static writeFeatures(Set<FeatureDefinition> features) {
415 «FOR feature : features»
417 «writeFeature(feature)»
423 def private static writeFeature(FeatureDefinition featureDef) {
425 feature «featureDef.QName.localName» {
426 «IF !featureDef.description.nullOrEmpty»
428 "«featureDef.description»";
430 «IF !featureDef.reference.nullOrEmpty»
432 "«featureDef.reference»";
434 «IF featureDef.status != null»
435 status «featureDef.status»;
441 def private static writeExtensions(List<ExtensionDefinition> extensions) {
443 «FOR anExtension : extensions»
444 «IF anExtension != null»
445 «writeExtension(anExtension)»
451 def private static writeExtension(ExtensionDefinition extensionDef) {
453 extension «extensionDef.QName.localName» {
454 «IF !extensionDef.description.nullOrEmpty»
456 "«extensionDef.description»";
458 «IF !extensionDef.argument.nullOrEmpty»
459 argument "«extensionDef.argument»";
461 «IF !extensionDef.reference.nullOrEmpty»
463 "«extensionDef.reference»";
465 «IF extensionDef.status != null»
466 status «extensionDef.status»;
472 def private static writeDeviations(Set<Deviation> deviations) {
474 «FOR deviation : deviations»
475 «IF deviation != null»
476 «writeDeviation(deviation)»
482 def private static writeDeviation(Deviation deviation) {
484 deviation «deviation.targetPath» {
485 «IF !deviation.reference.nullOrEmpty»
487 "«deviation.reference»";
489 «FOR dev : deviation.deviates»
490 «IF dev != null && dev.deviateType != null»
491 deviation «dev.deviateType.name»;
498 def private static writeAugments(Set<AugmentationSchema> augments) {
500 «FOR augment : augments»
502 «writeAugment(augment)»
508 def private static writeDataSchemaNodes(Collection<DataSchemaNode> dataSchemaNodes) {
510 «FOR schemaNode : dataSchemaNodes»
511 «writeDataSchemaNode(schemaNode)»
516 def private static CharSequence writeGroupingDefs(Set<GroupingDefinition> groupingDefs) {
518 «FOR groupingDef : groupingDefs»
519 «IF groupingDef != null»
520 «writeGroupingDef(groupingDef)»
526 def private static writeAugment(AugmentationSchema augment) {
528 augment «YangTextTemplate.formatToAugmentPath(augment.targetPath.pathFromRoot)» {
529 «IF augment.whenCondition != null && !augment.whenCondition.toString.nullOrEmpty»
530 when "«augment.whenCondition.toString»";
532 «IF !augment.description.nullOrEmpty»
534 "«augment.description»";
536 «IF !augment.reference.nullOrEmpty»
538 "«augment.reference»";
540 «IF augment.status != null»
541 status «augment.status»;
543 «IF !augment.childNodes.nullOrEmpty»
544 «writeDataSchemaNodes(augment.childNodes)»
546 «IF !augment.uses.nullOrEmpty»
547 «writeUsesNodes(augment.uses)»
553 def private static writeGroupingDef(GroupingDefinition groupingDef) {
554 var boolean isStatusDeprecated = groupingDef.status == Status::DEPRECATED
556 grouping «groupingDef.QName.localName» {
557 «IF !groupingDef.groupings.nullOrEmpty»
558 «writeGroupingDefs(groupingDef.groupings)»
560 «IF !groupingDef.childNodes.nullOrEmpty»
561 «writeDataSchemaNodes(groupingDef.childNodes)»
563 «IF isStatusDeprecated»
564 status «groupingDef.status»;
566 «IF !groupingDef.unknownSchemaNodes.nullOrEmpty»
567 «writeUnknownSchemaNodes(groupingDef.unknownSchemaNodes)»
573 def private static writeContSchemaNode(ContainerSchemaNode contSchemaNode) {
574 var boolean isStatusDeprecated = contSchemaNode.status == Status::DEPRECATED
576 container «contSchemaNode.getQName.localName» {
577 «IF !contSchemaNode.childNodes.nullOrEmpty»
578 «writeDataSchemaNodes(contSchemaNode.childNodes)»
580 «IF !contSchemaNode.availableAugmentations.nullOrEmpty»
581 «writeAugments(contSchemaNode.availableAugmentations)»
583 «IF !contSchemaNode.groupings.nullOrEmpty»
584 «writeGroupingDefs(contSchemaNode.groupings)»
586 «IF !contSchemaNode.uses.nullOrEmpty»
587 «writeUsesNodes(contSchemaNode.uses)»
589 «IF isStatusDeprecated»
590 status «contSchemaNode.status»;
592 «IF !contSchemaNode.unknownSchemaNodes.nullOrEmpty»
593 «writeUnknownSchemaNodes(contSchemaNode.unknownSchemaNodes)»
599 def private static writeAnyXmlSchemaNode(AnyXmlSchemaNode anyXmlSchemaNode) {
600 var boolean isStatusDeprecated = anyXmlSchemaNode.status == Status::DEPRECATED
602 anyxml «anyXmlSchemaNode.getQName.localName»«IF !isStatusDeprecated»;«ELSE» {
603 status «anyXmlSchemaNode.status»;
609 def private static writeLeafSchemaNode(LeafSchemaNode leafSchemaNode) {
610 var boolean isStatusDeprecated = leafSchemaNode.status == Status::DEPRECATED
612 leaf «leafSchemaNode.getQName.localName» {
613 type «leafSchemaNode.type.getQName.localName»;
614 «IF isStatusDeprecated»
615 status «leafSchemaNode.status»;
621 def private static writeLeafListSchemaNode(LeafListSchemaNode leafListSchemaNode) {
622 var boolean isStatusDeprecated = leafListSchemaNode.status == Status::DEPRECATED
624 leaf-list «leafListSchemaNode.getQName.localName» {
625 type «leafListSchemaNode.type.getQName.localName»;
626 «IF isStatusDeprecated»
627 status «leafListSchemaNode.status»;
633 def private static writeChoiceCaseNode(ChoiceCaseNode choiceCaseNode) {
634 var boolean isStatusDeprecated = choiceCaseNode.status == Status::DEPRECATED
636 case «choiceCaseNode.getQName.localName» {
637 «FOR childNode : choiceCaseNode.childNodes»
638 «writeDataSchemaNode(childNode)»
640 «IF isStatusDeprecated»
641 status «choiceCaseNode.status»;
647 def private static writeChoiceNode(ChoiceSchemaNode choiceNode) {
648 var boolean isStatusDeprecated = choiceNode.status == Status::DEPRECATED
650 choice «choiceNode.getQName.localName» {
651 «FOR child : choiceNode.cases»
652 «writeDataSchemaNode(child)»
654 «IF isStatusDeprecated»
655 status «choiceNode.status»;
661 def private static writeListSchemaNode(ListSchemaNode listSchemaNode) {
662 var boolean isStatusDeprecated = listSchemaNode.status == Status::DEPRECATED
665 list «listSchemaNode.getQName.localName» {
666 key «FOR listKey : listSchemaNode.keyDefinition SEPARATOR " "»"«listKey.localName»"
668 «IF !listSchemaNode.childNodes.nullOrEmpty»
669 «writeDataSchemaNodes(listSchemaNode.childNodes)»
671 «IF !listSchemaNode.availableAugmentations.nullOrEmpty»
672 «writeAugments(listSchemaNode.availableAugmentations)»
674 «IF !listSchemaNode.groupings.nullOrEmpty»
675 «writeGroupingDefs(listSchemaNode.groupings)»
677 «IF !listSchemaNode.uses.nullOrEmpty»
678 «writeUsesNodes(listSchemaNode.uses)»
680 «IF isStatusDeprecated»
681 status «listSchemaNode.status»;
683 «IF !listSchemaNode.unknownSchemaNodes.nullOrEmpty»
684 «writeUnknownSchemaNodes(listSchemaNode.unknownSchemaNodes)»
690 def private static CharSequence writeDataSchemaNode(DataSchemaNode child) {
692 «IF child instanceof ContainerSchemaNode»
693 «writeContSchemaNode(child)»
695 «IF child instanceof AnyXmlSchemaNode»
696 «writeAnyXmlSchemaNode(child)»
698 «IF child instanceof LeafSchemaNode»
699 «writeLeafSchemaNode(child)»
701 «IF child instanceof LeafListSchemaNode»
702 «writeLeafListSchemaNode(child)»
704 «IF child instanceof ChoiceCaseNode»
705 «writeChoiceCaseNode(child)»
707 «IF child instanceof ChoiceSchemaNode»
708 «writeChoiceNode(child)»
710 «IF child instanceof ListSchemaNode»
711 «writeListSchemaNode(child)»