From: Robert Varga Date: Wed, 25 Jan 2023 04:32:22 +0000 (+0100) Subject: Add SchemaInferenceStack.effectiveStatus() X-Git-Tag: v12.0.0~76 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=commitdiff_plain;h=384edb753b10971da6bfcb7bfb9bf84b78fb270a;p=yangtools.git Add SchemaInferenceStack.effectiveStatus() EffectiveStatements are lacking the equivalent of DocumentedNode.WithStatus.getStatus(). This patch introduces a utility method in SchemaInferenceStack, which acts as a replacement producing results well-defined in EffectiveStatement world. JIRA: YANGTOOLS-1272 Change-Id: I1b07d4ab2eb43c62090d526326ac10df901e8bfb Signed-off-by: Robert Varga --- diff --git a/model/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/SchemaInferenceStack.java b/model/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/SchemaInferenceStack.java index c5cde35a9d..5ad2966934 100644 --- a/model/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/SchemaInferenceStack.java +++ b/model/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/SchemaInferenceStack.java @@ -44,6 +44,7 @@ import org.opendaylight.yangtools.yang.model.api.PathExpression.DerefSteps; import org.opendaylight.yangtools.yang.model.api.PathExpression.LocationPathSteps; import org.opendaylight.yangtools.yang.model.api.PathExpression.Steps; import org.opendaylight.yangtools.yang.model.api.SchemaTreeInference; +import org.opendaylight.yangtools.yang.model.api.Status; import org.opendaylight.yangtools.yang.model.api.TypeAware; import org.opendaylight.yangtools.yang.model.api.TypeDefinition; import org.opendaylight.yangtools.yang.model.api.TypedDataSchemaNode; @@ -58,6 +59,7 @@ import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier; import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Absolute; import org.opendaylight.yangtools.yang.model.api.stmt.SchemaTreeAwareEffectiveStatement; import org.opendaylight.yangtools.yang.model.api.stmt.SchemaTreeEffectiveStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.StatusEffectiveStatement; import org.opendaylight.yangtools.yang.model.api.stmt.TypedefAwareEffectiveStatement; import org.opendaylight.yangtools.yang.model.api.stmt.TypedefEffectiveStatement; import org.opendaylight.yangtools.yang.model.api.type.InstanceIdentifierTypeDefinition; @@ -367,6 +369,48 @@ public final class SchemaInferenceStack implements Mutable, EffectiveModelContex return groupingDepth != 0; } + /** + * Return the effective {@code status} of the {@link #currentStatement()}, if present. This method operates on + * the effective view of the model and therefore does not reflect status the declaration hierarchy. Most notably + * this YANG snippet: + *
+     * {@code
+     *   module foo {
+     *     grouping foo {
+     *       status obsolete;
+     *       leaf bar { type string; }
+     *     }
+     *
+     *     container foo {
+     *       status deprecated;
+     *       uses bar;
+     *     }
+     *
+     *     uses foo;
+     *   }
+     * }
+     * 
+ * will cause this method to report the status of {@code leaf bar} as: + * + * + * @return {@link Status#CURRENT} if {@link #isEmpty()}, or the status of current statement as implied by its direct + * and its ancestors' substaments. + */ + public @NonNull Status effectiveStatus() { + final var it = reconstructDeque().descendingIterator(); + while (it.hasNext()) { + final var optStatus = it.next().findFirstEffectiveSubstatementArgument(StatusEffectiveStatement.class); + if (optStatus.isPresent()) { + return optStatus.orElseThrow(); + } + } + return Status.CURRENT; + } + /** * Reset this stack to empty state. */ @@ -694,12 +738,15 @@ public final class SchemaInferenceStack implements Mutable, EffectiveModelContex */ public @NonNull SchemaTreeInference toSchemaTreeInference() { checkState(inInstantiatedContext(), "Cannot convert uninstantiated context %s", this); - final var cleanDeque = clean ? deque : reconstructSchemaInferenceStack().deque; - return DefaultSchemaTreeInference.unsafeOf(getEffectiveModelContext(), cleanDeque.stream() + return DefaultSchemaTreeInference.unsafeOf(getEffectiveModelContext(), reconstructDeque().stream() .map(stmt -> (SchemaTreeEffectiveStatement) stmt) .collect(ImmutableList.toImmutableList())); } + private ArrayDeque> reconstructDeque() { + return clean ? deque : reconstructSchemaInferenceStack().deque; + } + /** * Convert current state into an absolute schema node identifier. * diff --git a/model/yang-model-util/src/test/java/org/opendaylight/yangtools/yang/model/util/SchemaInferenceStackTest.java b/model/yang-model-util/src/test/java/org/opendaylight/yangtools/yang/model/util/SchemaInferenceStackTest.java index 76284ebbae..ccf51e90f8 100644 --- a/model/yang-model-util/src/test/java/org/opendaylight/yangtools/yang/model/util/SchemaInferenceStackTest.java +++ b/model/yang-model-util/src/test/java/org/opendaylight/yangtools/yang/model/util/SchemaInferenceStackTest.java @@ -28,6 +28,7 @@ import org.opendaylight.yangtools.yang.model.api.GroupingDefinition; import org.opendaylight.yangtools.yang.model.api.Module; import org.opendaylight.yangtools.yang.model.api.PathExpression; import org.opendaylight.yangtools.yang.model.api.PathExpression.LocationPathSteps; +import org.opendaylight.yangtools.yang.model.api.Status; import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils; import org.opendaylight.yangtools.yang.xpath.api.YangLocationPath; import org.opendaylight.yangtools.yang.xpath.api.YangXPathAxis; @@ -99,6 +100,46 @@ class SchemaInferenceStackTest { assertNotExistentTypedef(stack, "schema parent (uri:my-module?revision=2014-10-07)my-container"); } + @Test + void rootIsCurrent() { + final var stack = SchemaInferenceStack.of(context); + assertEquals(Status.CURRENT, stack.effectiveStatus()); + } + + @Test + void myGroupingIsCurrent() { + final var stack = SchemaInferenceStack.of(context); + stack.enterGrouping(QName.create(myModule.getQNameModule(), "my-grouping")); + assertEquals(Status.CURRENT, stack.effectiveStatus()); + } + + @Test + void myLeafInContainerIsDeprecated() { + final var stack = SchemaInferenceStack.of(context); + stack.enterDataTree(QName.create(myModule.getQNameModule(), "my-container")); + stack.enterDataTree(QName.create(myModule.getQNameModule(), "my-leaf-in-container")); + assertEquals(Status.DEPRECATED, stack.effectiveStatus()); + } + + @Test + void twoInGroupingIsObsolete() { + final var stack = SchemaInferenceStack.of(context); + stack.enterGrouping(QName.create(myModule.getQNameModule(), "my-name")); + stack.enterDataTree(QName.create(myModule.getQNameModule(), "two")); + assertEquals(Status.OBSOLETE, stack.effectiveStatus()); + } + + @Test + void twoInMyNameInputIsObsolete() { + final var stack = SchemaInferenceStack.of(context); + stack.enterSchemaTree(QName.create(myModule.getQNameModule(), "my-name")); + stack.enterSchemaTree(QName.create(myModule.getQNameModule(), "input")); + stack.enterSchemaTree(QName.create(myModule.getQNameModule(), "my-choice")); + stack.enterSchemaTree(QName.create(myModule.getQNameModule(), "case-two")); + stack.enterSchemaTree(QName.create(myModule.getQNameModule(), "two")); + assertEquals(Status.OBSOLETE, stack.effectiveStatus()); + } + private static void assertNotExistentGrouping(final SchemaInferenceStack stack, final String parentDesc) { final QName nonExistent = QName.create(myModule.getQNameModule(), "non-existent"); assertEquals("Grouping (uri:my-module?revision=2014-10-07)non-existent not present in " + parentDesc, diff --git a/model/yang-model-util/src/test/resources/schema-context-util/my-module.yang b/model/yang-model-util/src/test/resources/schema-context-util/my-module.yang index f4b1d99f41..c99930324e 100644 --- a/model/yang-model-util/src/test/resources/schema-context-util/my-module.yang +++ b/model/yang-model-util/src/test/resources/schema-context-util/my-module.yang @@ -29,6 +29,7 @@ module my-module { container my-container { leaf my-leaf-in-container { type int32; + status deprecated; } uses my-grouping; list my-list { @@ -118,14 +119,11 @@ module my-module { grouping my-name { choice my-choice { case case-one { - container one { - //empty - } + container one; } case case-two { - container two { - //empty - } + container two; + status obsolete; } } }