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;
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;
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:
+ * <pre>
+ * {@code
+ * module foo {
+ * grouping foo {
+ * status obsolete;
+ * leaf bar { type string; }
+ * }
+ *
+ * container foo {
+ * status deprecated;
+ * uses bar;
+ * }
+ *
+ * uses foo;
+ * }
+ * }
+ * </pre>
+ * will cause this method to report the status of {@code leaf bar} as:
+ * <ul>
+ * <li>{@link Status#OBSOLETE} at its original declaration site in {@code grouping foo}</li>
+ * <li>{@link Status#DEPRECATED} at its instantiation in {@code container foo}</li>
+ * <li>{@link Status#CURRENT} at its instantiation in {@code module foo}</li>
+ * </ul>
+ *
+ * @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.
*/
*/
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<EffectiveStatement<?, ?>> reconstructDeque() {
+ return clean ? deque : reconstructSchemaInferenceStack().deque;
+ }
+
/**
* Convert current state into an absolute schema node identifier.
*
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;
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,