From: Ruslan Kashapov Date: Tue, 15 Nov 2022 15:41:31 +0000 (+0200) Subject: Fix NPE when parsing deviation from submodule X-Git-Tag: v10.0.1~12 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=commitdiff_plain;h=274de5b85ab4626c0ba6f79c38e8dd2e5b0eddcb;p=yangtools.git Fix NPE when parsing deviation from submodule If the deviation statement is used in a submodule, we need to lookup up the corresponding module, otherwise we will not find the correct namespace. JIRA: YANGTOOLS-1448 Change-Id: Iaf2e1d6526a9f268a6c0a3835e1bfdfafa05fffe Signed-off-by: Ruslan Kashapov Signed-off-by: Robert Varga --- diff --git a/parser/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/meta/DeviationStatementSupport.java b/parser/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/meta/DeviationStatementSupport.java index 1e4e7c8e00..00a0cfaa64 100644 --- a/parser/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/meta/DeviationStatementSupport.java +++ b/parser/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/meta/DeviationStatementSupport.java @@ -7,9 +7,10 @@ */ package org.opendaylight.yangtools.yang.parser.rfc7950.stmt.meta; +import static com.google.common.base.Verify.verifyNotNull; + import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterables; -import org.opendaylight.yangtools.yang.common.QNameModule; import org.opendaylight.yangtools.yang.model.api.YangStmtMapping; import org.opendaylight.yangtools.yang.model.api.meta.DeclarationReference; import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement; @@ -17,6 +18,7 @@ import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; import org.opendaylight.yangtools.yang.model.api.stmt.DeviationEffectiveStatement; import org.opendaylight.yangtools.yang.model.api.stmt.DeviationStatement; import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Absolute; +import org.opendaylight.yangtools.yang.model.api.stmt.SubmoduleStatement; import org.opendaylight.yangtools.yang.model.ri.stmt.DeclaredStatementDecorators; import org.opendaylight.yangtools.yang.model.ri.stmt.DeclaredStatements; import org.opendaylight.yangtools.yang.model.ri.stmt.EffectiveStatements; @@ -53,9 +55,17 @@ public final class DeviationStatementSupport public void onFullDefinitionDeclared(final Mutable ctx) { super.onFullDefinitionDeclared(ctx); - final QNameModule currentModule = ctx.getFromNamespace(ParserNamespaces.MODULECTX_TO_QNAME, ctx.getRoot()); - final QNameModule targetModule = Iterables.getLast(ctx.getArgument().getNodeIdentifiers()).getModule(); + StmtContext root = ctx.getRoot(); + if (root.producesDeclared(SubmoduleStatement.class)) { + // root is submodule, we need to find the module we belong to. We can rely on there being exactly one + // belongs-to statement, enforced SubmoduleStatementSupport's validator. + root = Iterables.getOnlyElement( + root.getAllFromNamespace(ParserNamespaces.BELONGSTO_PREFIX_TO_MODULECTX).values()); + } + final var currentModule = verifyNotNull(ctx.getFromNamespace(ParserNamespaces.MODULECTX_TO_QNAME, root), + "Failed to find QName for %s", root); + final var targetModule = Iterables.getLast(ctx.getArgument().getNodeIdentifiers()).getModule(); if (currentModule.equals(targetModule)) { throw new InferenceException(ctx, "Deviation must not target the same module as the one it is defined in: %s", currentModule); diff --git a/parser/yang-parser-rfc7950/src/test/java/org/opendaylight/yangtools/yang/stmt/YT1448Test.java b/parser/yang-parser-rfc7950/src/test/java/org/opendaylight/yangtools/yang/stmt/YT1448Test.java new file mode 100644 index 0000000000..404b46ce16 --- /dev/null +++ b/parser/yang-parser-rfc7950/src/test/java/org/opendaylight/yangtools/yang/stmt/YT1448Test.java @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2022 PANTHEON.tech s.r.o. 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.hamcrest.CoreMatchers.startsWith; + +import org.junit.Test; + +public class YT1448Test extends AbstractYangTest { + + @Test + public void deviationFromSubmodule() { + assertEffectiveModelDir("/bugs/YT1448/valid"); + } + + @Test + public void deviationFromSubmoduleTargetedOwnModule() { + assertInferenceExceptionDir("/bugs/YT1448/invalid", + startsWith("Deviation must not target the same module as the one it is defined in")); + } +} diff --git a/parser/yang-parser-rfc7950/src/test/resources/bugs/YT1448/invalid/foo-submodule.yang b/parser/yang-parser-rfc7950/src/test/resources/bugs/YT1448/invalid/foo-submodule.yang new file mode 100644 index 0000000000..3d8ac916ee --- /dev/null +++ b/parser/yang-parser-rfc7950/src/test/resources/bugs/YT1448/invalid/foo-submodule.yang @@ -0,0 +1,13 @@ +submodule foo-submodule { + yang-version 1.1; + + belongs-to foo { + prefix foo; + } + + revision 2020-10-21; + + deviation "/foo:object/foo:items/foo:boolean" { + deviate not-supported ; + } +} diff --git a/parser/yang-parser-rfc7950/src/test/resources/bugs/YT1448/invalid/foo.yang b/parser/yang-parser-rfc7950/src/test/resources/bugs/YT1448/invalid/foo.yang new file mode 100644 index 0000000000..c3cf60e550 --- /dev/null +++ b/parser/yang-parser-rfc7950/src/test/resources/bugs/YT1448/invalid/foo.yang @@ -0,0 +1,25 @@ +module foo { + yang-version 1.1; + namespace "urn:test:foo"; + prefix foo; + + include foo-submodule; + + revision 2022-02-22; + + container object { + list items { + key "name"; + leaf name { + type string; + } + leaf str { + type string; + } + leaf boolean { + type boolean; + } + } + } + +} diff --git a/parser/yang-parser-rfc7950/src/test/resources/bugs/YT1448/valid/bar.yang b/parser/yang-parser-rfc7950/src/test/resources/bugs/YT1448/valid/bar.yang new file mode 100644 index 0000000000..23a192d0a0 --- /dev/null +++ b/parser/yang-parser-rfc7950/src/test/resources/bugs/YT1448/valid/bar.yang @@ -0,0 +1,22 @@ +module bar { + yang-version 1.1; + namespace "urn:test:bar"; + prefix bar; + + revision 2022-02-22; + + container object { + list items { + key "name"; + leaf name { + type string; + } + leaf str { + type string; + } + leaf boolean { + type boolean; + } + } + } +} diff --git a/parser/yang-parser-rfc7950/src/test/resources/bugs/YT1448/valid/foo-submodule.yang b/parser/yang-parser-rfc7950/src/test/resources/bugs/YT1448/valid/foo-submodule.yang new file mode 100644 index 0000000000..2ed4aa8e06 --- /dev/null +++ b/parser/yang-parser-rfc7950/src/test/resources/bugs/YT1448/valid/foo-submodule.yang @@ -0,0 +1,17 @@ +submodule foo-submodule { + yang-version 1.1; + + belongs-to foo { + prefix foo; + } + + import bar { + prefix bar; + } + + revision 2020-10-21; + + deviation "/bar:object/bar:items/bar:boolean" { + deviate not-supported ; + } +} diff --git a/parser/yang-parser-rfc7950/src/test/resources/bugs/YT1448/valid/foo.yang b/parser/yang-parser-rfc7950/src/test/resources/bugs/YT1448/valid/foo.yang new file mode 100644 index 0000000000..a29b6d7b2f --- /dev/null +++ b/parser/yang-parser-rfc7950/src/test/resources/bugs/YT1448/valid/foo.yang @@ -0,0 +1,19 @@ +module foo { + yang-version 1.1; + namespace "urn:test:foo"; + prefix foo; + + include foo-submodule; + + revision 2022-02-22; + + container object { + list items { + key "name"; + leaf name { + type string; + } + } + } + +}