Flatten submodule hierarchy for YangModuleInfo 70/82670/1
authorAnna Bencurova <Anna.Bencurova@pantheon.tech>
Mon, 10 Jun 2019 12:55:49 +0000 (14:55 +0200)
committerRobert Varga <nite@hq.sk>
Sun, 23 Jun 2019 19:20:48 +0000 (19:20 +0000)
YANG inherently contains modules and submodules, where submodules
do not really have further submodules. While YANG 1.0 allowed
inclusion of submodules in other submodules, and that is modeled
in yang-model-api, this practice has been deprecated with YANG 1.1.

If we are faced with multiple such includes, for example both
module and submodule including a second submodule, we could end up
generating superfluous classes, just to represent the second
submodule twice (once for module's purposes and once for submodule's
purposes) -- hence when all of them are collected recursively, we
would end up with two distinct instances for the same source.

Since submodules are not directly visible outside of the main class,
this hierarchy is not public API and is a purely internal thing.

This patch re-organizes generation so that we present all submodules
as dependencies of the main module, which automatically solves the
problem, while also making for nicer class layout, as we do not get
multiply-nested classes.

JIRA: MDSAL-457
Change-Id: Ic78edaf852f3497f3c4c96fdca3a77de30b7f8c1
Signed-off-by: Anna Bencurova <Anna.Bencurova@pantheon.tech>
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
(cherry picked from commit 4a8ae0d2fbffc56edc956cde9a9ecde28f3e9a34)

binding/mdsal-binding-java-api-generator/src/main/java/org/opendaylight/mdsal/binding/java/api/generator/YangModuleInfoTemplate.xtend

index 714445ca560a60627b73ff898183acf040a10b9e..643e4cdc0ad3070f5105a218e5645659838e1bca 100644 (file)
@@ -67,6 +67,9 @@ class YangModuleInfoTemplate {
     }
 
     def String generate() {
+        val Set<Module> submodules = new HashSet
+        collectSubmodules(submodules, module)
+
         val body = '''
             public final class «MODULE_INFO_CLASS_NAME» extends «ResourceYangModuleInfo.importedName» {
                 «val rev = module.revision»
@@ -83,7 +86,7 @@ class YangModuleInfoTemplate {
                     return «QName.importedName».create(NAME, localName).intern();
                 }
 
-                «classBody(module, MODULE_INFO_CLASS_NAME)»
+                «classBody(module, MODULE_INFO_CLASS_NAME, submodules
             }
         '''
         return '''
@@ -109,9 +112,17 @@ class YangModuleInfoTemplate {
 
     }
 
-    private def CharSequence classBody(Module m, String className) '''
+    private static def void collectSubmodules(Set<Module> dest, Module module) {
+        for (Module submodule : module.submodules) {
+            if (dest.add(submodule)) {
+                collectSubmodules(dest, submodule)
+            }
+        }
+    }
+
+    private def CharSequence classBody(Module m, String className, Set<Module> submodules) '''
         private «className»() {
-            «IF !m.imports.empty || !m.submodules.empty»
+            «IF !m.imports.empty || !submodules.empty»
                 «Set.importedName»<«YangModuleInfo.importedName»> set = new «HashSet.importedName»<>();
             «ENDIF»
             «IF !m.imports.empty»
@@ -132,12 +143,10 @@ class YangModuleInfoTemplate {
                     «ENDIF»
                 «ENDFOR»
             «ENDIF»
-            «IF !m.submodules.empty»
-                «FOR submodule : m.submodules»
-                    set.add(«submodule.name.className»Info.getInstance());
-                «ENDFOR»
-            «ENDIF»
-            «IF m.imports.empty && m.submodules.empty»
+            «FOR submodule : submodules»
+                set.add(«submodule.name.className»Info.getInstance());
+            «ENDFOR»
+            «IF m.imports.empty && submodules.empty»
                 importedModules = «Collections.importedName».emptySet();
             «ELSE»
                 importedModules = «ImmutableSet.importedName».copyOf(set);
@@ -158,9 +167,7 @@ class YangModuleInfoTemplate {
         public «Set.importedName»<«YangModuleInfo.importedName»> getImportedModules() {
             return importedModules;
         }
-
-        «generateSubInfo(m)»
-
+        «generateSubInfo(submodules)»
     '''
 
     private def sourcePath(Module module) {
@@ -269,9 +276,10 @@ class YangModuleInfoTemplate {
         return builder.toString()
     }
 
-    private def generateSubInfo(Module module) '''
-        «FOR submodule : module.submodules»
+    private def generateSubInfo(Set<Module> submodules) '''
+        «FOR submodule : submodules»
             «val className = submodule.name.className»
+
             private static final class «className»Info extends «ResourceYangModuleInfo.importedName» {
                 «val rev = submodule.revision»
                 private final «QName.importedName» NAME = «QName.importedName».create("«
@@ -284,7 +292,7 @@ class YangModuleInfoTemplate {
                     return INSTANCE;
                 }
 
-                «classBody(submodule, className + "Info")»
+                «classBody(submodule, className + "Info", Collections.emptySet
             }
         «ENDFOR»
     '''