Resolve generated type for leafrefs targetting unions 67/91367/1
authorTomas Cere <tomas.cere@pantheon.tech>
Fri, 10 Jul 2020 11:51:54 +0000 (13:51 +0200)
committerRobert Varga <robert.varga@pantheon.tech>
Fri, 17 Jul 2020 09:59:01 +0000 (11:59 +0200)
We need to be able to resolve the generated type of unions
which are targeted by leafrefs during codegen.
Introduce a path that attempts this by consulting ModuleContext
for the generated types in case we are resolving a leafref.

JIRA: MDSAL-572
Change-Id: I40448a4c9f2fdf26280e0911ebb9dcc5fc60d3f1
Signed-off-by: Tomas Cere <tomas.cere@pantheon.tech>
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
(cherry picked from commit 8c4ab985c1723336640324789c65489e71deb4e0)

binding/mdsal-binding-generator-impl/src/main/java/org/opendaylight/mdsal/binding/generator/impl/AbstractTypeGenerator.java
binding/mdsal-binding-generator-impl/src/main/java/org/opendaylight/mdsal/binding/yang/types/AbstractTypeProvider.java
binding/mdsal-binding-generator-impl/src/test/java/org/opendaylight/mdsal/binding/generator/impl/Mdsal572Test.java [new file with mode: 0644]
binding/mdsal-binding-generator-impl/src/test/resources/mdsal572.yang [new file with mode: 0644]

index 37d420554a46174d55b3a712189f42d150379b98..ad38a54df0de6c05f4b3de8205ec6f45782e6bc0 100644 (file)
@@ -118,10 +118,12 @@ import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.opendaylight.yangtools.yang.model.api.SchemaNode;
 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.TypedDataSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.UsesNode;
 import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition;
 import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.LeafrefTypeDefinition;
 import org.opendaylight.yangtools.yang.model.api.type.PatternConstraint;
 import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition;
 import org.opendaylight.yangtools.yang.model.util.ModuleDependencySort;
@@ -1424,13 +1426,25 @@ abstract class AbstractTypeGenerator {
                     returnType = genTOBuilder.build();
                 }
             } else {
-                // It is constrained version of already declared type (inner declared type exists,
-                // onlyfor special cases (Enum, Union, Bits), which were already checked.
-                // In order to get proper class we need to look up closest derived type
-                // and apply restrictions from leaf type
+                // It is constrained version of already declared type (inner declared type exists, only for special
+                // cases (Enum, Union, Bits), which were already checked.
+                // In order to get proper class we need to look up closest derived type and apply restrictions from leaf
+                // type
                 final Restrictions restrictions = BindingGeneratorUtil.getRestrictions(typeDef);
-                returnType = typeProvider.javaTypeForSchemaDefinitionType(getBaseOrDeclaredType(typeDef), leaf,
-                        restrictions, inGrouping);
+                final TypeDefinition<?> baseOrDeclaredType = getBaseOrDeclaredType(typeDef);
+                // we need to try to lookup an already generated type in case the leafref is targetting a generated type
+                if (baseOrDeclaredType instanceof LeafrefTypeDefinition) {
+                    final SchemaNode leafrefTarget =
+                            typeProvider.getTargetForLeafref((LeafrefTypeDefinition) baseOrDeclaredType, leaf);
+                    if (leafrefTarget instanceof TypedDataSchemaNode) {
+                        returnType = context.getInnerType(((TypedDataSchemaNode) leafrefTarget).getType().getPath());
+                    }
+                }
+                if (returnType == null) {
+                    returnType = typeProvider.javaTypeForSchemaDefinitionType(baseOrDeclaredType, leaf,
+                            restrictions, inGrouping);
+                }
+
                 addPatternConstant(typeBuilder, leaf.getQName().getLocalName(), restrictions.getPatternConstraints());
             }
         } else {
index 24f11dffee589a726771253b30e3f4d99c8336f0..cd8716d19e666e6e1bc5dd1110b998d501bf7495 100644 (file)
@@ -220,6 +220,17 @@ public abstract class AbstractTypeProvider implements TypeProvider {
         return returnType;
     }
 
+    public SchemaNode getTargetForLeafref(final LeafrefTypeDefinition leafrefType, final SchemaNode parentNode) {
+        final PathExpression xpath = leafrefType.getPathStatement();
+        Preconditions.checkArgument(xpath != null, "The Path Statement for Leafref Type Definition cannot be NULL!");
+
+        final Module module = findParentModule(schemaContext, parentNode);
+        Preconditions.checkArgument(module != null, "Failed to find module for parent %s", parentNode);
+
+        return xpath.isAbsolute() ? findDataTreeSchemaNode(schemaContext, module.getQNameModule(), xpath)
+                : findDataSchemaNodeForRelativeXPath(schemaContext, module, parentNode, xpath);
+    }
+
     private GeneratedTransferObject shadedTOWithRestrictions(final GeneratedTransferObject gto,
             final Restrictions restrictions) {
         final GeneratedTOBuilder gtob = newGeneratedTOBuilder(gto.getIdentifier());
diff --git a/binding/mdsal-binding-generator-impl/src/test/java/org/opendaylight/mdsal/binding/generator/impl/Mdsal572Test.java b/binding/mdsal-binding-generator-impl/src/test/java/org/opendaylight/mdsal/binding/generator/impl/Mdsal572Test.java
new file mode 100644 (file)
index 0000000..c59c896
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2020 PANTHEON.tech, s.r.o. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.mdsal.binding.generator.impl;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.List;
+import org.junit.Test;
+import org.opendaylight.mdsal.binding.model.api.Type;
+import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
+
+public class Mdsal572Test {
+    @Test
+    public void mdsal572Test() {
+        final List<Type> types = new BindingGeneratorImpl().generateTypes(YangParserTestUtils.parseYangResource(
+                "/mdsal572.yang"));
+        assertEquals(6, types.size());
+    }
+}
diff --git a/binding/mdsal-binding-generator-impl/src/test/resources/mdsal572.yang b/binding/mdsal-binding-generator-impl/src/test/resources/mdsal572.yang
new file mode 100644 (file)
index 0000000..533c9db
--- /dev/null
@@ -0,0 +1,30 @@
+module mdsal572 {
+  namespace "mdsal572";
+  prefix l;
+
+  grouping state-top {
+    leaf index {
+      type union {
+        type enumeration {
+          enum ALL;
+        }
+        type uint32;
+      }
+    }
+  }
+
+  grouping g {
+    list l {
+      container state {
+        uses state-top;
+      }
+      leaf index {
+        type leafref {
+          path "../state/index";
+        }
+      }
+    }
+  }
+
+  uses g;
+}
\ No newline at end of file