package org.opendaylight.yangtools.rfc8040.model.api;
import com.google.common.annotations.Beta;
-import org.eclipse.jdt.annotation.NonNull;
import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
-import org.opendaylight.yangtools.yang.model.api.stmt.ContainerEffectiveStatement;
import org.opendaylight.yangtools.yang.model.api.stmt.DataTreeAwareEffectiveStatement;
import org.opendaylight.yangtools.yang.model.api.stmt.UnknownEffectiveStatement;
default StatementDefinition statementDefinition() {
return YangDataStatements.YANG_DATA;
}
-
- /**
- * Return the container statement defined in this yang-data statement instance.
- *
- * @return container statement
- */
- @NonNull ContainerEffectiveStatement getContainer();
}
package org.opendaylight.yangtools.rfc8040.model.api;
import com.google.common.annotations.Beta;
-import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
/**
* Represents 'yang-data' extension statement defined in
* <a href="https://tools.ietf.org/html/rfc8040#section-8">RFC8040</a>. This statement must appear as a top-level
- * statement, otherwise it is ignored and does not appear in the final schema context. It must contain exactly one
- * top-level container node (directly or indirectly via a uses statement).
+ * statement, otherwise it is ignored and does not appear in the final schema context.
*/
@Beta
-public interface YangDataSchemaNode extends UnknownSchemaNode {
- /**
- * Returns container schema node container within this yang-data definition.
- *
- * @return container schema node
- */
- ContainerSchemaNode getContainerSchemaNode();
-
+public interface YangDataSchemaNode extends UnknownSchemaNode, DataNodeContainer {
@Override
YangDataEffectiveStatement asEffectiveStatement();
}
+++ /dev/null
-/*
- * 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.yangtools.rfc8040.parser;
-
-import com.google.common.annotations.Beta;
-import org.eclipse.jdt.annotation.NonNull;
-import org.opendaylight.yangtools.yang.common.Empty;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour;
-import org.opendaylight.yangtools.yang.parser.spi.meta.ParserNamespace;
-
-/**
- * Namespace for remembering the {@code yang-data} argument's QName.
- */
-@Beta
-// FIXME: We should not be needing this namespace, as yang-data's argument is not documented anywhere to be compatible
-// with 'identifier', hence we cannot safely form a QName.
-public final class YangDataArgumentNamespace {
- public static final @NonNull ParserNamespace<Empty, QName> INSTANCE = new ParserNamespace<>("yangDataArgument");
- public static final @NonNull NamespaceBehaviour<? ,?> BEHAVIOUR = NamespaceBehaviour.statementLocal(INSTANCE);
-
- private YangDataArgumentNamespace() {
- // Hidden on purpose
- }
-}
import org.opendaylight.yangtools.rfc8040.model.api.YangDataSchemaNode;
import org.opendaylight.yangtools.rfc8040.model.api.YangDataStatement;
import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace;
-import org.opendaylight.yangtools.yang.model.api.stmt.ContainerEffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.DataTreeAwareEffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.DataTreeEffectiveStatement;
import org.opendaylight.yangtools.yang.model.spi.meta.AbstractEffectiveUnknownSchmemaNode;
+import org.opendaylight.yangtools.yang.model.spi.meta.EffectiveStatementMixins.DataNodeContainerMixin;
import org.opendaylight.yangtools.yang.parser.spi.meta.EffectiveStmtCtx.Current;
@Beta
final class YangDataEffectiveStatementImpl extends AbstractEffectiveUnknownSchmemaNode<String, YangDataStatement>
- implements YangDataEffectiveStatement, YangDataSchemaNode {
- private final @NonNull QName argumentQName;
- private final @NonNull ContainerEffectiveStatement container;
+ implements YangDataEffectiveStatement, YangDataSchemaNode, DataNodeContainerMixin<String, YangDataStatement> {
+ private final @NonNull DataSchemaNode child;
YangDataEffectiveStatementImpl(final Current<String, YangDataStatement> stmt,
- final ImmutableList<? extends EffectiveStatement<?, ?>> substatements, final QName qname) {
+ final ImmutableList<? extends EffectiveStatement<?, ?>> substatements, final DataSchemaNode child) {
super(stmt.declared(), stmt.argument(), stmt.history(), substatements);
- argumentQName = requireNonNull(qname);
-
- container = findFirstEffectiveSubstatement(ContainerEffectiveStatement.class).get();
-
- // TODO: this is strong binding of two API contracts. Unfortunately ContainerEffectiveStatement design is
- // incomplete.
- verify(container instanceof ContainerSchemaNode, "Incompatible container %s", container);
+ this.child = requireNonNull(child);
}
@Override
public QName getQName() {
- return argumentQName;
- }
-
- @Override
- public ContainerEffectiveStatement getContainer() {
- return container;
+ return child.getQName();
}
@Override
- public ContainerSchemaNode getContainerSchemaNode() {
- // Verified in the constructor
- return (ContainerSchemaNode) container;
+ public DataSchemaNode dataChildByName(final QName name) {
+ return name.equals(child.getQName()) ? child : null;
}
@Override
@Override
protected <K, V, N extends IdentifierNamespace<K, V>> Optional<? extends Map<K, V>> getNamespaceContents(
final Class<N> namespace) {
- if (SchemaTreeNamespace.class.equals(namespace) || DataTreeNamespace.class.equals(namespace)) {
- @SuppressWarnings("unchecked")
- final Map<K, V> ns = (Map<K, V>)Map.of(container.argument(), container);
- return Optional.of(ns);
+ if (SchemaTreeNamespace.class.equals(namespace)) {
+ return castChild();
+ }
+ if (DataTreeNamespace.class.equals(namespace)) {
+ if (child instanceof DataTreeEffectiveStatement) {
+ return castChild();
+ }
+
+ // A schema tree statement which *has to* know about data tree -- just forward it
+ verify(child instanceof DataTreeAwareEffectiveStatement, "Unexpected child %s", child);
+ return Optional.of(((DataTreeAwareEffectiveStatement<?, ?>) child).getAll(namespace));
}
return super.getNamespaceContents(namespace);
}
+
+ @SuppressWarnings("unchecked")
+ private <K, V> Optional<Map<K, V>> castChild() {
+ return Optional.of((Map<K, V>) Map.of(child.getQName(), child));
+ }
}
*/
package org.opendaylight.yangtools.rfc8040.parser;
-import static com.google.common.base.Verify.verifyNotNull;
+import static com.google.common.base.Verify.verify;
import com.google.common.annotations.Beta;
import com.google.common.collect.ImmutableList;
+import java.util.stream.Collectors;
import org.opendaylight.yangtools.rfc8040.model.api.YangDataEffectiveStatement;
import org.opendaylight.yangtools.rfc8040.model.api.YangDataStatement;
import org.opendaylight.yangtools.rfc8040.model.api.YangDataStatements;
-import org.opendaylight.yangtools.yang.common.Empty;
-import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
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;
import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.ChoiceEffectiveStatement;
import org.opendaylight.yangtools.yang.model.api.stmt.DataTreeEffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.SchemaTreeEffectiveStatement;
import org.opendaylight.yangtools.yang.model.api.stmt.UsesEffectiveStatement;
import org.opendaylight.yangtools.yang.parser.api.YangParserConfiguration;
import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractStringStatementSupport;
import org.opendaylight.yangtools.yang.parser.spi.meta.InvalidSubstatementException;
import org.opendaylight.yangtools.yang.parser.spi.meta.MissingSubstatementException;
import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.Mutable;
-import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils;
import org.opendaylight.yangtools.yang.parser.spi.meta.SubstatementValidator;
import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
@Beta
public final class YangDataStatementSupport
extends AbstractStringStatementSupport<YangDataStatement, YangDataEffectiveStatement> {
+ // As per RFC8040 page 81:
+ //
+ // The substatements of this extension MUST follow the
+ // 'data-def-stmt' rule in the YANG ABNF.
+ //
+ // As per RFC7950 page 185:
+ //
+ // data-def-stmt = container-stmt /
+ // leaf-stmt /
+ // leaf-list-stmt /
+ // list-stmt /
+ // choice-stmt /
+ // anydata-stmt /
+ // anyxml-stmt /
+ // uses-stmt
+ //
+ // The cardinality is not exactly constrained, but the entirety of substatements are required to resolve to a single
+ // XML document (page 80). This is enforced when we arrive at full declaration.
private static final SubstatementValidator VALIDATOR = SubstatementValidator.builder(YangDataStatements.YANG_DATA)
- .addMandatory(YangStmtMapping.CONTAINER)
- .addOptional(YangStmtMapping.USES)
+ .addAny(YangStmtMapping.CONTAINER)
+ .addAny(YangStmtMapping.LEAF)
+ .addAny(YangStmtMapping.LEAF_LIST)
+ .addAny(YangStmtMapping.LIST)
+ .addAny(YangStmtMapping.CHOICE)
+ .addAny(YangStmtMapping.ANYDATA)
+ .addAny(YangStmtMapping.ANYXML)
+ .addAny(YangStmtMapping.USES)
.build();
public YangDataStatementSupport(final YangParserConfiguration config) {
@Override
public void onFullDefinitionDeclared(final Mutable<String, YangDataStatement, YangDataEffectiveStatement> ctx) {
- // Parse and populate our argument to be picked up when we build the effective statement
- final String argument = SourceException.throwIfNull(ctx.argument(), ctx, "yang-data requires an argument");
- final QName qname = StmtContextUtils.parseIdentifier(ctx, argument);
- ctx.addToNs(YangDataArgumentNamespace.INSTANCE, Empty.value(), qname);
+ // If we are declared in an illegal place, this becomes a no-op
+ if (!ctx.isSupportedToBuildEffective()) {
+ return;
+ }
+
+ // Run SubstatementValidator-based validation first
+ super.onFullDefinitionDeclared(ctx);
// Support for 'operations' container semantics. For this we need to recognize when the model at hand matches
// RFC8040 ietf-restconf module. In ordered to do that we hook onto this particular definition:
// }
//
// If we find it, we hook an inference action which performs the next step when the module is fully declared.
- if (ctx.isSupportedToBuildEffective() && "yang-api".equals(ctx.argument())) {
+ if ("yang-api".equals(ctx.argument())) {
final var stmts = ctx.declaredSubstatements();
if (stmts.size() == 1) {
final var stmt = stmts.iterator().next();
@Override
protected YangDataEffectiveStatement createEffective(final Current<String, YangDataStatement> stmt,
final ImmutableList<? extends EffectiveStatement<?, ?>> substatements) {
- // So now we need to deal with effective validation. The requirement is that:
- // It MUST contain data definition statements
- // that result in exactly one container data node definition.
- final long dataDefs = substatements.stream().filter(DataTreeEffectiveStatement.class::isInstance).count();
- if (dataDefs == 0) {
- throw new MissingSubstatementException("yang-data requires exactly one container", stmt.sourceReference());
- }
- if (dataDefs > 1) {
- throw new InvalidSubstatementException(stmt,
- "yang-data requires exactly one data definition node, found %s", dataDefs);
- }
+ // RFC8040 page 80 requires that:
+ // It MUST contain data definition statements
+ // that result in exactly one container data node definition.
+ // An instance of a YANG data template can thus be translated
+ // into an XML instance document, whose top-level element
+ // corresponds to the top-level container.
+ //
+ // We validate this additional constraint when we arrive at the effective model, with the view that
+ // 'container data node definition' is really meant to say 'XML element'.
+ //
+ // This really boils down to the requirement to have a single schema tree substatement, which needs to either
+ // be a data tree statement or a choice statement.
+ final var schemaSub = substatements.stream()
+ .filter(SchemaTreeEffectiveStatement.class::isInstance)
+ .map(SchemaTreeEffectiveStatement.class::cast)
+ .collect(Collectors.toUnmodifiableList());
+ final var child = switch (schemaSub.size()) {
+ case 0 -> throw new MissingSubstatementException(stmt, "yang-data requires at least one substatement");
+ case 1 -> {
+ final SchemaTreeEffectiveStatement<?> substmt = schemaSub.get(0);
+ SourceException.throwIf(
+ !(substmt instanceof ChoiceEffectiveStatement) && !(substmt instanceof DataTreeEffectiveStatement),
+ stmt, "%s is not a recognized container data node definition", substmt);
+ verify(substmt instanceof DataSchemaNode, "Unexpected single child %s", substmt);
+ yield (DataSchemaNode) substmt;
+ }
+ default -> throw new InvalidSubstatementException(stmt,
+ "yang-data requires exactly one container data node definition, found %s", schemaSub);
+ };
- return new YangDataEffectiveStatementImpl(stmt, substatements,
- verifyNotNull(stmt.namespaceItem(YangDataArgumentNamespace.INSTANCE, Empty.value())));
+ return new YangDataEffectiveStatementImpl(stmt, substatements, child);
}
}
@BeforeClass
public static void createReactor() {
REACTOR = RFC7950Reactors.vanillaReactorBuilder()
- .addNamespaceSupport(ModelProcessingPhase.FULL_DECLARATION, YangDataArgumentNamespace.BEHAVIOUR)
.addStatementSupport(ModelProcessingPhase.FULL_DECLARATION,
new YangDataStatementSupport(YangParserConfiguration.DEFAULT))
.build();
--- /dev/null
+/*
+ * Copyright (c) 2022 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.yangtools.rfc8040.parser;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+import org.junit.Test;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
+
+public class YT1443Test extends AbstractYangDataTest {
+ @Test
+ public void buildEffectiveModelTest() throws ReactorException {
+ final var module = REACTOR.newBuild()
+ .addSources(IETF_RESTCONF_MODULE, sourceForResource("/yt1443.yang"))
+ .buildEffective()
+ .findModuleStatement(QName.create("yt1443", "yt1443"))
+ .orElseThrow();
+ assertNotNull(module);
+ }
+}
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThrows;
-import static org.junit.Assert.assertTrue;
import com.google.common.collect.ImmutableSet;
import java.util.Collection;
import org.opendaylight.yangtools.yang.common.Revision;
import org.opendaylight.yangtools.yang.common.XMLNamespace;
import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
import org.opendaylight.yangtools.yang.model.api.ExtensionDefinition;
import org.opendaylight.yangtools.yang.model.api.Module;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
private static final Revision REVISION = Revision.of("2017-06-01");
private static final QNameModule FOO_QNAMEMODULE = QNameModule.create(XMLNamespace.of("foo"), REVISION);
- private static final QName MY_YANG_DATA_A = QName.create(FOO_QNAMEMODULE, "my-yang-data-a");
- private static final QName MY_YANG_DATA_B = QName.create(FOO_QNAMEMODULE, "my-yang-data-b");
@Test
public void testYangData() throws Exception {
YangDataSchemaNode myYangDataANode = null;
YangDataSchemaNode myYangDataBNode = null;
for (final UnknownSchemaNode unknownSchemaNode : unknownSchemaNodes) {
- assertTrue(unknownSchemaNode instanceof YangDataSchemaNode);
+ assertThat(unknownSchemaNode, instanceOf(YangDataSchemaNode.class));
final YangDataSchemaNode yangDataSchemaNode = (YangDataSchemaNode) unknownSchemaNode;
- if (MY_YANG_DATA_A.equals(yangDataSchemaNode.getQName())) {
+ if ("my-yang-data-a".equals(yangDataSchemaNode.getNodeParameter())) {
myYangDataANode = yangDataSchemaNode;
- } else if (MY_YANG_DATA_B.equals(yangDataSchemaNode.getQName())) {
+ } else if ("my-yang-data-b".equals(yangDataSchemaNode.getNodeParameter())) {
myYangDataBNode = yangDataSchemaNode;
}
}
assertNotNull(myYangDataANode);
assertNotNull(myYangDataBNode);
-
- assertNotNull(myYangDataANode.getContainerSchemaNode());
- assertNotNull(myYangDataBNode.getContainerSchemaNode());
}
@Test
assertEquals(1, unknownSchemaNodes.size());
final UnknownSchemaNode unknownSchemaNode = unknownSchemaNodes.iterator().next();
- assertTrue(unknownSchemaNode instanceof YangDataSchemaNode);
+ assertThat(unknownSchemaNode, instanceOf(YangDataSchemaNode.class));
final YangDataSchemaNode myYangDataNode = (YangDataSchemaNode) unknownSchemaNode;
assertNotNull(myYangDataNode);
- final ContainerSchemaNode contInYangData = myYangDataNode.getContainerSchemaNode();
- assertNotNull(contInYangData);
+ final Collection<? extends DataSchemaNode> yangDataChildren = myYangDataNode.getChildNodes();
+ assertEquals(1, yangDataChildren.size());
+
+ final DataSchemaNode childInYangData = yangDataChildren.iterator().next();
+ assertThat(childInYangData, instanceOf(ContainerSchemaNode.class));
+ final ContainerSchemaNode contInYangData = (ContainerSchemaNode) childInYangData;
assertEquals(Optional.empty(), contInYangData.effectiveConfig());
- final ContainerSchemaNode innerCont = (ContainerSchemaNode) contInYangData.findDataChildByName(
- QName.create(baz.getQNameModule(), "inner-cont")).get();
+ final ContainerSchemaNode innerCont = (ContainerSchemaNode) contInYangData.getDataChildByName(
+ QName.create(baz.getQNameModule(), "inner-cont"));
assertNotNull(innerCont);
assertEquals(Optional.empty(), innerCont.effectiveConfig());
- final ContainerSchemaNode grpCont = (ContainerSchemaNode) contInYangData.findDataChildByName(
- QName.create(baz.getQNameModule(), "grp-cont")).get();
+ final ContainerSchemaNode grpCont = (ContainerSchemaNode) contInYangData.getDataChildByName(
+ QName.create(baz.getQNameModule(), "grp-cont"));
assertNotNull(grpCont);
assertEquals(Optional.empty(), grpCont.effectiveConfig());
}
assertEquals(1, unknownSchemaNodes.size());
final UnknownSchemaNode unknownSchemaNode = unknownSchemaNodes.iterator().next();
- assertTrue(unknownSchemaNode instanceof YangDataSchemaNode);
+ assertThat(unknownSchemaNode, instanceOf(YangDataSchemaNode.class));
final YangDataSchemaNode myYangDataNode = (YangDataSchemaNode) unknownSchemaNode;
assertNotNull(myYangDataNode);
- final ContainerSchemaNode contInYangData = myYangDataNode.getContainerSchemaNode();
- assertNotNull(contInYangData);
- final ContainerSchemaNode innerCont = (ContainerSchemaNode) contInYangData.findDataChildByName(
- QName.create(foobar.getQNameModule(), "inner-cont")).get();
+ final Collection<? extends DataSchemaNode> yangDataChildren = myYangDataNode.getChildNodes();
+ assertEquals(1, yangDataChildren.size());
+
+ final DataSchemaNode childInYangData = yangDataChildren.iterator().next();
+ assertThat(childInYangData, instanceOf(ContainerSchemaNode.class));
+ final ContainerSchemaNode contInYangData = (ContainerSchemaNode) childInYangData;
+ final ContainerSchemaNode innerCont = (ContainerSchemaNode) contInYangData.getDataChildByName(
+ QName.create(foobar.getQNameModule(), "inner-cont"));
assertNotNull(innerCont);
- final ContainerSchemaNode grpCont = (ContainerSchemaNode) contInYangData.findDataChildByName(
- QName.create(foobar.getQNameModule(), "grp-cont")).get();
+ final ContainerSchemaNode grpCont = (ContainerSchemaNode) contInYangData.getDataChildByName(
+ QName.create(foobar.getQNameModule(), "grp-cont"));
assertNotNull(grpCont);
}
assertNotNull(schemaContext);
final Module bar = schemaContext.findModule("bar", REVISION).get();
- final ContainerSchemaNode cont = (ContainerSchemaNode) bar.findDataChildByName(
- QName.create(bar.getQNameModule(), "cont")).get();
+ final ContainerSchemaNode cont = (ContainerSchemaNode) bar.getDataChildByName(
+ QName.create(bar.getQNameModule(), "cont"));
assertNotNull(cont);
final Collection<? extends ExtensionDefinition> extensions = schemaContext.getExtensions();
final ReactorException ex = assertThrows(ReactorException.class, () -> build.buildEffective());
final Throwable cause = ex.getCause();
assertThat(cause, instanceOf(MissingSubstatementException.class));
- assertThat(cause.getMessage(), startsWith("yang-data requires exactly one container"));
+ assertThat(cause.getMessage(), startsWith("yang-data requires at least one substatement [at "));
}
@Test
final ReactorException ex = assertThrows(ReactorException.class, () -> build.buildEffective());
final Throwable cause = ex.getCause();
assertThat(cause, instanceOf(InvalidSubstatementException.class));
- assertThat(cause.getMessage(), startsWith("yang-data requires exactly one data definition node, found 2"));
+ assertThat(cause.getMessage(),
+ startsWith("yang-data requires exactly one container data node definition, found ["));
}
}
--- /dev/null
+module yt1443 {
+ yang-version 1.1;
+ namespace "yt1443";
+ prefix "yt1443";
+
+ import ietf-restconf { prefix rc; }
+
+ rc:yang-data support-save-data {
+ anydata support-save-data;
+ }
+}
import org.opendaylight.yangtools.rfc6643.parser.OidStatementSupport;
import org.opendaylight.yangtools.rfc6643.parser.SubIdStatementSupport;
import org.opendaylight.yangtools.rfc7952.parser.AnnotationStatementSupport;
-import org.opendaylight.yangtools.rfc8040.parser.YangDataArgumentNamespace;
import org.opendaylight.yangtools.rfc8040.parser.YangDataStatementSupport;
import org.opendaylight.yangtools.rfc8528.parser.MountPointStatementSupport;
import org.opendaylight.yangtools.rfc8639.parser.SubscriptionStateNotificationStatementSupport;
.addStatementSupport(ModelProcessingPhase.FULL_DECLARATION, new AnnotationStatementSupport(config))
// RFC8040 yang-data support
- .addNamespaceSupport(ModelProcessingPhase.FULL_DECLARATION, YangDataArgumentNamespace.BEHAVIOUR)
.addStatementSupport(ModelProcessingPhase.FULL_DECLARATION, new YangDataStatementSupport(config))
// RFC8528 mount-point support