Bug 9242: Reuse deviating statement contexts 06/64406/4
authorIgor Foltin <igor.foltin@pantheon.tech>
Tue, 17 Oct 2017 14:08:18 +0000 (16:08 +0200)
committerRobert Varga <nite@hq.sk>
Tue, 24 Oct 2017 09:23:13 +0000 (09:23 +0000)
In the process of deviate add/replace resolution we make
copies of deviated statement contexts which are then added
to the deviation target context.

However, making copies of these statement contexts is not
necessary except the ones which represent unknown statements.

Therefore, reuse them during the resolution of deviate add/replace.

By doing this, we also solve the failing deviate replace with
user-defined types as statement contexts that represent deviating
user-defined types are now resolved within their original context.

Change-Id: Ie61a38e270ef648fe61ea283805d149533c10f62
Signed-off-by: Igor Foltin <igor.foltin@pantheon.tech>
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/DeviateStatementImpl.java
yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/Bug9242Test.java [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/bugs/bug9242/imp-module-2.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/bugs/bug9242/imp-module.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/bugs/bug9242/root-module.yang [new file with mode: 0644]

index b87656fd100a4e5e65a96c51d7165fedb170ea44..88b8990f4e9bf757fecc5d5907e4e33f655cdb3c 100644 (file)
@@ -231,7 +231,7 @@ public class DeviateStatementImpl extends AbstractDeclaredStatement<DeviateKind>
                 }
             }
 
-            targetCtx.addEffectiveSubstatement(targetCtx.childCopyOf(stmtCtxToBeAdded, CopyType.ORIGINAL));
+            copyStatement(stmtCtxToBeAdded, targetCtx);
         }
 
         private static void performDeviateReplace(final StatementContextBase<?, ?, ?> deviateStmtCtx,
@@ -257,7 +257,7 @@ public class DeviateStatementImpl extends AbstractDeclaredStatement<DeviateKind>
             for (final StmtContext<?, ?, ?> targetCtxSubstatement : targetCtx.effectiveSubstatements()) {
                 if (stmtToBeReplaced.equals(targetCtxSubstatement.getPublicDefinition())) {
                     targetCtx.removeStatementFromEffectiveSubstatements(stmtToBeReplaced);
-                    targetCtx.addEffectiveSubstatement(targetCtx.childCopyOf(stmtCtxToBeReplaced, CopyType.ORIGINAL));
+                    copyStatement(stmtCtxToBeReplaced, targetCtx);
                     return;
                 }
             }
@@ -265,7 +265,7 @@ public class DeviateStatementImpl extends AbstractDeclaredStatement<DeviateKind>
             for (final Mutable<?, ?, ?> targetCtxSubstatement : targetCtx.mutableDeclaredSubstatements()) {
                 if (stmtToBeReplaced.equals(targetCtxSubstatement.getPublicDefinition())) {
                     targetCtxSubstatement.setIsSupportedToBuildEffective(false);
-                    targetCtx.addEffectiveSubstatement(targetCtx.childCopyOf(stmtCtxToBeReplaced, CopyType.ORIGINAL));
+                    copyStatement(stmtCtxToBeReplaced, targetCtx);
                     return;
                 }
             }
@@ -317,6 +317,17 @@ public class DeviateStatementImpl extends AbstractDeclaredStatement<DeviateKind>
                     targetCtx.getStatementArgument(), stmtCtxToBeDeleted.getStatementSourceReference());
         }
 
+        private static void copyStatement(final Mutable<?, ?, ?> stmtCtxToBeCopied,
+                final StatementContextBase<?, ?, ?> targetCtx) {
+            // we need to make a copy of the statement context only if it is an unknown statement, otherwise
+            // we can reuse the original statement context
+            if (!StmtContextUtils.isUnknownStatement(stmtCtxToBeCopied)) {
+                targetCtx.addEffectiveSubstatement(stmtCtxToBeCopied);
+            } else {
+                targetCtx.addEffectiveSubstatement(targetCtx.childCopyOf(stmtCtxToBeCopied, CopyType.ORIGINAL));
+            }
+        }
+
         private static boolean statementsAreEqual(final StatementDefinition firstStmtDef, final String firstStmtArg,
                 final StatementDefinition secondStmtDef, final String secondStmtArg) {
             return firstStmtDef.equals(secondStmtDef) && Objects.equals(firstStmtArg, secondStmtArg);
diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/Bug9242Test.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/Bug9242Test.java
new file mode 100644 (file)
index 0000000..feb93e6
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2017 Pantheon Technologies 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.yangtools.yang.stmt;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertSame;
+
+import java.util.Date;
+import org.junit.Test;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil;
+import org.opendaylight.yangtools.yang.model.api.Deviation;
+import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
+
+public class Bug9242Test {
+
+    @Test
+    public void testDeviateReplaceWithUserDefinedTypes() throws Exception {
+        final SchemaContext schemaContext = StmtTestUtils.parseYangSources("/bugs/bug9242/");
+        assertNotNull(schemaContext);
+
+        final Date revision = SimpleDateFormatUtil.getRevisionFormat().parse("2017-10-13");
+
+        final Module rootModule = schemaContext.findModuleByName("root-module", revision);
+        final Module impModule = schemaContext.findModuleByName("imp-module", revision);
+        assertNotNull(impModule);
+
+        TypeDefinition<?> deviatedMyLeafType = null;
+        TypeDefinition<?> deviatedMyLeaf2Type = null;
+
+        for (final Deviation deviation : rootModule.getDeviations()) {
+            if (deviation.getTargetPath().getLastComponent().equals(QName.create(
+                    impModule.getQNameModule(), "my-leaf"))) {
+                deviatedMyLeafType = deviation.getDeviates().iterator().next().getDeviatedType();
+            }
+
+            if (deviation.getTargetPath().getLastComponent().equals(QName.create(
+                    impModule.getQNameModule(), "my-leaf-2"))) {
+                deviatedMyLeaf2Type = deviation.getDeviates().iterator().next().getDeviatedType();
+            }
+        }
+
+        assertNotNull(deviatedMyLeafType);
+        assertNotNull(deviatedMyLeaf2Type);
+
+        final LeafSchemaNode myLeaf = (LeafSchemaNode) impModule.getDataChildByName(QName.create(
+                impModule.getQNameModule(), "my-leaf"));
+        assertSame(deviatedMyLeafType, myLeaf.getType());
+
+        final LeafSchemaNode myLeaf2 = (LeafSchemaNode) impModule.getDataChildByName(QName.create(
+                impModule.getQNameModule(), "my-leaf-2"));
+        assertSame(deviatedMyLeaf2Type, myLeaf2.getType());
+    }
+}
diff --git a/yang/yang-parser-impl/src/test/resources/bugs/bug9242/imp-module-2.yang b/yang/yang-parser-impl/src/test/resources/bugs/bug9242/imp-module-2.yang
new file mode 100644 (file)
index 0000000..0636c31
--- /dev/null
@@ -0,0 +1,12 @@
+module imp-module-2 {
+    namespace imp2-ns;
+    prefix imp2;
+
+    revision 2017-10-13;
+
+    typedef new-type {
+        type string {
+            length 10..15;
+        }
+    }
+}
\ No newline at end of file
diff --git a/yang/yang-parser-impl/src/test/resources/bugs/bug9242/imp-module.yang b/yang/yang-parser-impl/src/test/resources/bugs/bug9242/imp-module.yang
new file mode 100644 (file)
index 0000000..b26b6c5
--- /dev/null
@@ -0,0 +1,14 @@
+module imp-module {
+    namespace imp-ns;
+    prefix imp;
+
+    revision 2017-10-13;
+
+    leaf my-leaf {
+        type string;
+    }
+
+    leaf my-leaf-2 {
+        type string;
+    }
+}
\ No newline at end of file
diff --git a/yang/yang-parser-impl/src/test/resources/bugs/bug9242/root-module.yang b/yang/yang-parser-impl/src/test/resources/bugs/bug9242/root-module.yang
new file mode 100644 (file)
index 0000000..b5c0005
--- /dev/null
@@ -0,0 +1,32 @@
+module root-module {
+    namespace rm-ns;
+    prefix rm;
+
+    import imp-module {
+        prefix im;
+    }
+
+    import imp-module-2 {
+        prefix im2;
+    }
+
+    revision 2017-10-13;
+
+    deviation "/im:my-leaf" {
+        deviate replace {
+            type im2:new-type;
+        }
+    }
+
+    deviation "/im:my-leaf-2" {
+        deviate replace {
+            type new-type;
+        }
+    }
+
+    typedef new-type {
+        type int32 {
+            range 10..15;
+        }
+    }
+}
\ No newline at end of file