Update YangData(Effective)Statement definition 20/104720/6
authorRobert Varga <robert.varga@pantheon.tech>
Thu, 2 Mar 2023 13:02:05 +0000 (14:02 +0100)
committerRobert Varga <nite@hq.sk>
Mon, 6 Mar 2023 14:44:55 +0000 (14:44 +0000)
Using a raw String is not nice for end users, who want to corelate
this statement to other constructs. Change the argument definition
to YangDataName.

JIRA: YANGTOOLS-1479
Change-Id: I0b7788d9c6c9736ddac466c9c63a3cc05b6c92f9
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
model/rfc8040-model-api/src/main/java/org/opendaylight/yangtools/rfc8040/model/api/YangDataEffectiveStatement.java
model/rfc8040-model-api/src/main/java/org/opendaylight/yangtools/rfc8040/model/api/YangDataStatement.java
model/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/SchemaInferenceStack.java
model/yang-model-util/src/test/java/org/opendaylight/yangtools/yang/model/util/YT1297Test.java
parser/rfc8040-parser-support/src/main/java/org/opendaylight/yangtools/rfc8040/parser/RefYangDataStatement.java
parser/rfc8040-parser-support/src/main/java/org/opendaylight/yangtools/rfc8040/parser/YangDataEffectiveStatementImpl.java
parser/rfc8040-parser-support/src/main/java/org/opendaylight/yangtools/rfc8040/parser/YangDataStatementImpl.java
parser/rfc8040-parser-support/src/main/java/org/opendaylight/yangtools/rfc8040/parser/YangDataStatementSupport.java
parser/rfc8040-parser-support/src/test/java/org/opendaylight/yangtools/rfc8040/parser/YT1338Test.java

index e437cf2135678fa75fded867ee4f37d674948d2f..5bbf4df84a49300c8065795cfacbf447a784a55d 100644 (file)
@@ -7,7 +7,7 @@
  */
 package org.opendaylight.yangtools.rfc8040.model.api;
 
-import com.google.common.annotations.Beta;
+import org.opendaylight.yangtools.yang.common.YangDataName;
 import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
 import org.opendaylight.yangtools.yang.model.api.stmt.DataTreeAwareEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.UnknownEffectiveStatement;
@@ -16,9 +16,8 @@ import org.opendaylight.yangtools.yang.model.api.stmt.UnknownEffectiveStatement;
  * Effective statement representation of 'yang-data' extension defined in
  * <a href="https://tools.ietf.org/html/rfc8040#section-8">RFC 8040</a>.
  */
-@Beta
-public interface YangDataEffectiveStatement extends UnknownEffectiveStatement<String, YangDataStatement>,
-        DataTreeAwareEffectiveStatement<String, YangDataStatement> {
+public interface YangDataEffectiveStatement extends UnknownEffectiveStatement<YangDataName, YangDataStatement>,
+        DataTreeAwareEffectiveStatement<YangDataName, YangDataStatement> {
     @Override
     default StatementDefinition statementDefinition() {
         return YangDataStatements.YANG_DATA;
index 2b8aad0958882a5f47d16d26d1f33e6474caec6b..dabf4b041ef3e190c60b4b74ec1f04575fb7bf9d 100644 (file)
@@ -7,7 +7,7 @@
  */
 package org.opendaylight.yangtools.rfc8040.model.api;
 
-import com.google.common.annotations.Beta;
+import org.opendaylight.yangtools.yang.common.YangDataName;
 import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
 import org.opendaylight.yangtools.yang.model.api.stmt.UnknownStatement;
 
@@ -15,8 +15,7 @@ import org.opendaylight.yangtools.yang.model.api.stmt.UnknownStatement;
  * Declared statement representation of 'yang-data' extension defined in
  * <a href="https://tools.ietf.org/html/rfc8040#section-8">RFC 8040</a>.
  */
-@Beta
-public interface YangDataStatement extends UnknownStatement<String> {
+public interface YangDataStatement extends UnknownStatement<YangDataName> {
     @Override
     default StatementDefinition statementDefinition() {
         return YangDataStatements.YANG_DATA;
index d4bbcb730256ec2cfd56c93977700d42bc699666..e05d2e32556c1bd8ce1d6c9ff15f74943542d89b 100644 (file)
@@ -34,6 +34,7 @@ import org.opendaylight.yangtools.yang.common.AbstractQName;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.common.QNameModule;
 import org.opendaylight.yangtools.yang.common.UnresolvedQName.Unqualified;
+import org.opendaylight.yangtools.yang.common.YangDataName;
 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContextProvider;
 import org.opendaylight.yangtools.yang.model.api.EffectiveStatementInference;
@@ -488,26 +489,26 @@ public final class SchemaInferenceStack implements Mutable, EffectiveModelContex
     /**
      * Lookup a {@code rc:yang-data} by the module namespace where it is defined and its template name.
      *
-     * @param namespace Module namespace in which to lookup the template
      * @param name Template name
      * @return Resolved yang-data
-     * @throws NullPointerException if any argument is null
+     * @throws NullPointerException if any argument is {@code null}
      * @throws IllegalArgumentException if the corresponding yang-data cannot be found
      * @throws IllegalStateException if this stack is not empty
      */
-    public @NonNull YangDataEffectiveStatement enterYangData(final QNameModule namespace, final String name) {
+    public @NonNull YangDataEffectiveStatement enterYangData(final YangDataName name) {
         final EffectiveStatement<?, ?> parent = deque.peekLast();
         checkState(parent == null, "Cannot lookup yang-data in a non-empty stack");
 
-        final String templateName = requireNonNull(name);
-        final ModuleEffectiveStatement module = effectiveModel.getModuleStatements().get(requireNonNull(namespace));
+        final var checkedName = requireNonNull(name);
+        final var namespace = name.module();
+        final ModuleEffectiveStatement module = effectiveModel.getModuleStatements().get(namespace);
         checkArgument(module != null, "Module for %s not found", namespace);
 
         final YangDataEffectiveStatement ret = module.streamEffectiveSubstatements(YangDataEffectiveStatement.class)
-            .filter(stmt -> templateName.equals(stmt.argument()))
+            .filter(stmt -> checkedName.equals(stmt.argument()))
             .findFirst()
             .orElseThrow(
-                () -> new IllegalArgumentException("yang-data " + templateName + " not present in " + namespace));
+                () -> new IllegalArgumentException("yang-data " + checkedName.name() + " not present in " + namespace));
         deque.addLast(ret);
         currentModule = module;
         return ret;
index 685ae83535983e7225aea5eb2db50b7e1c0503a1..ccb3b0c43cce3f0c80347c29918cd858df0c5617 100644 (file)
@@ -17,6 +17,7 @@ import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.common.QNameModule;
 import org.opendaylight.yangtools.yang.common.Revision;
 import org.opendaylight.yangtools.yang.common.XMLNamespace;
+import org.opendaylight.yangtools.yang.common.YangDataName;
 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
 import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
 
@@ -37,19 +38,22 @@ public class YT1297Test {
 
     @Test
     public void testEnterYangData() {
-        assertNotNull(stack.enterYangData(RESTCONF, "yang-api"));
+        assertNotNull(stack.enterYangData(new YangDataName(RESTCONF, "yang-api")));
         assertNotNull(stack.enterDataTree(QName.create(RESTCONF, "restconf")));
     }
 
     @Test
     public void testEnterYangDataNegative() {
-        Exception ex = assertThrows(IllegalArgumentException.class, () -> stack.enterYangData(RESTCONF, "bad-name"));
+        Exception ex = assertThrows(IllegalArgumentException.class,
+            () -> stack.enterYangData(new YangDataName(RESTCONF, "bad-name")));
         assertEquals("yang-data bad-name not present in " + RESTCONF, ex.getMessage());
-        ex = assertThrows(IllegalArgumentException.class, () -> stack.enterYangData(BAD_MODULE, "whatever"));
+        ex = assertThrows(IllegalArgumentException.class,
+            () -> stack.enterYangData(new YangDataName(BAD_MODULE, "whatever")));
         assertEquals("Module for " + BAD_MODULE + " not found", ex.getMessage());
 
         assertNotNull(stack.enterGrouping(QName.create(RESTCONF, "errors")));
-        ex = assertThrows(IllegalStateException.class, () -> stack.enterYangData(RESTCONF, "yang-api"));
+        ex = assertThrows(IllegalStateException.class,
+            () -> stack.enterYangData(new YangDataName(RESTCONF, "yang-api")));
         assertEquals("Cannot lookup yang-data in a non-empty stack", ex.getMessage());
     }
 }
index 1e9aef766390b85276d949784cf27ef37e12d491..1090b06971f6585cfd6e89533885c1207f5d2092 100644 (file)
@@ -8,10 +8,12 @@
 package org.opendaylight.yangtools.rfc8040.parser;
 
 import org.opendaylight.yangtools.rfc8040.model.api.YangDataStatement;
+import org.opendaylight.yangtools.yang.common.YangDataName;
 import org.opendaylight.yangtools.yang.model.api.meta.DeclarationReference;
 import org.opendaylight.yangtools.yang.model.spi.meta.AbstractRefStatement;
 
-final class RefYangDataStatement extends AbstractRefStatement<String, YangDataStatement> implements YangDataStatement {
+final class RefYangDataStatement extends AbstractRefStatement<YangDataName, YangDataStatement>
+        implements YangDataStatement {
     RefYangDataStatement(final YangDataStatement delegate, final DeclarationReference ref) {
         super(delegate, ref);
     }
index 444cf3f3e17f58094577c297ceb80fd9749d969e..3e4d6d9a35d7714dfe4d41a0358e7147f2a6eeb4 100644 (file)
@@ -20,6 +20,7 @@ import org.opendaylight.yangtools.rfc8040.model.api.YangDataEffectiveStatement;
 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.common.YangDataName;
 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.DataTreeAwareEffectiveStatement;
@@ -30,11 +31,13 @@ import org.opendaylight.yangtools.yang.model.spi.meta.EffectiveStatementMixins.D
 import org.opendaylight.yangtools.yang.parser.spi.meta.EffectiveStmtCtx.Current;
 
 @Beta
-final class YangDataEffectiveStatementImpl extends AbstractEffectiveUnknownSchmemaNode<String, YangDataStatement>
-        implements YangDataEffectiveStatement, YangDataSchemaNode, DataNodeContainerMixin<String, YangDataStatement> {
+final class YangDataEffectiveStatementImpl
+        extends AbstractEffectiveUnknownSchmemaNode<YangDataName, YangDataStatement>
+        implements YangDataEffectiveStatement, YangDataSchemaNode,
+                   DataNodeContainerMixin<YangDataName, YangDataStatement> {
     private final @NonNull DataSchemaNode child;
 
-    YangDataEffectiveStatementImpl(final Current<String, YangDataStatement> stmt,
+    YangDataEffectiveStatementImpl(final Current<YangDataName, YangDataStatement> stmt,
              final ImmutableList<? extends EffectiveStatement<?, ?>> substatements, final DataSchemaNode child) {
         super(stmt.declared(), stmt.argument(), stmt.history(), substatements);
         this.child = requireNonNull(child);
@@ -85,7 +88,7 @@ final class YangDataEffectiveStatementImpl extends AbstractEffectiveUnknownSchme
     }
 
     @Override
-    public Optional<SchemaTreeEffectiveStatement<?>> findSchemaTreeNode(@NonNull QName qname) {
+    public Optional<SchemaTreeEffectiveStatement<?>> findSchemaTreeNode(final QName qname) {
         return qname.equals(child.getQName()) ? (Optional) Optional.of(child) : Optional.empty();
     }
 }
index 4582ac81def919f4a2484dd3ea23ffac3ff16b67..4ff8d9592da76132431506d1578193e955a123c5 100644 (file)
@@ -9,15 +9,17 @@ package org.opendaylight.yangtools.rfc8040.parser;
 
 import com.google.common.collect.ImmutableList;
 import org.opendaylight.yangtools.rfc8040.model.api.YangDataStatement;
+import org.opendaylight.yangtools.yang.common.YangDataName;
 import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
-import org.opendaylight.yangtools.yang.model.spi.meta.AbstractDeclaredStatement.WithRawStringArgument.WithSubstatements;
+import org.opendaylight.yangtools.yang.model.spi.meta.AbstractDeclaredStatement.WithArgument.WithSubstatements;
 
 /**
  * Declared statement representation of 'yang-data' extension defined in
  * <a href="https://tools.ietf.org/html/rfc8040#section-8">RFC 8040</a>.
  */
-final class YangDataStatementImpl extends WithSubstatements implements YangDataStatement {
-    YangDataStatementImpl(final String rawArgument, final ImmutableList<? extends DeclaredStatement<?>> substatements) {
-        super(rawArgument, substatements);
+final class YangDataStatementImpl extends WithSubstatements<YangDataName> implements YangDataStatement {
+    YangDataStatementImpl(final YangDataName argument,
+            final ImmutableList<? extends DeclaredStatement<?>> substatements) {
+        super(argument.name(), argument, substatements);
     }
 }
\ No newline at end of file
index 7b316290cc92310ed3fe0c48fe7be9f30e1bdcbf..73cf81973b70ecfee71239fb4f87df41acab582f 100644 (file)
@@ -10,11 +10,14 @@ package org.opendaylight.yangtools.rfc8040.parser;
 import static com.google.common.base.Verify.verify;
 
 import com.google.common.annotations.Beta;
+import com.google.common.annotations.VisibleForTesting;
 import com.google.common.collect.ImmutableList;
 import java.util.stream.Collectors;
+import org.opendaylight.yangtools.rfc8040.model.api.YangDataConstants;
 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.YangDataName;
 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;
@@ -25,18 +28,20 @@ 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.AbstractStatementSupport;
 import org.opendaylight.yangtools.yang.parser.spi.meta.BoundStmtCtx;
 import org.opendaylight.yangtools.yang.parser.spi.meta.EffectiveStmtCtx.Current;
 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;
 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> {
+        extends AbstractStatementSupport<YangDataName, YangDataStatement, YangDataEffectiveStatement> {
     // As per RFC8040 page 81:
     //
     //    The substatements of this extension MUST follow the
@@ -66,12 +71,24 @@ public final class YangDataStatementSupport
         .addAny(YangStmtMapping.USES)
         .build();
 
+    @VisibleForTesting
+    static final YangDataName YANG_API = new YangDataName(YangDataConstants.RFC8040_MODULE, "yang-api");
+
     public YangDataStatementSupport(final YangParserConfiguration config) {
         super(YangDataStatements.YANG_DATA, StatementPolicy.reject(), config, VALIDATOR);
     }
 
     @Override
-    public void onStatementAdded(final Mutable<String, YangDataStatement, YangDataEffectiveStatement> ctx) {
+    public YangDataName parseArgumentValue(final StmtContext<?, ?, ?> ctx, final String value) {
+        try {
+            return new YangDataName(StmtContextUtils.getModuleQName(ctx.getRoot()), value);
+        } catch (IllegalArgumentException e) {
+            throw new SourceException(ctx, e, "Invalid yang-data argument %s", value);
+        }
+    }
+
+    @Override
+    public void onStatementAdded(final Mutable<YangDataName, YangDataStatement, YangDataEffectiveStatement> ctx) {
         // as per https://tools.ietf.org/html/rfc8040#section-8,
         // yang-data is ignored unless it appears as a top-level statement
         if (ctx.coerceParentContext().getParentContext() != null) {
@@ -80,7 +97,8 @@ public final class YangDataStatementSupport
     }
 
     @Override
-    public void onFullDefinitionDeclared(final Mutable<String, YangDataStatement, YangDataEffectiveStatement> ctx) {
+    public void onFullDefinitionDeclared(
+            final Mutable<YangDataName, YangDataStatement, YangDataEffectiveStatement> ctx) {
         // If we are declared in an illegal place, this becomes a no-op
         if (!ctx.isSupportedToBuildEffective()) {
             return;
@@ -97,7 +115,7 @@ public final class YangDataStatementSupport
         //   }
         //
         // If we find it, we hook an inference action which performs the next step when the module is fully declared.
-        if ("yang-api".equals(ctx.argument())) {
+        if (YANG_API.equals(ctx.getArgument())) {
             final var stmts = ctx.declaredSubstatements();
             if (stmts.size() == 1) {
                 final var stmt = stmts.iterator().next();
@@ -121,9 +139,9 @@ public final class YangDataStatementSupport
     }
 
     @Override
-    protected YangDataStatement createDeclared(final BoundStmtCtx<String> ctx,
+    protected YangDataStatement createDeclared(final BoundStmtCtx<YangDataName> ctx,
             final ImmutableList<DeclaredStatement<?>> substatements) {
-        return new YangDataStatementImpl(ctx.getRawArgument(), substatements);
+        return new YangDataStatementImpl(ctx.getArgument(), substatements);
     }
 
     @Override
@@ -133,7 +151,7 @@ public final class YangDataStatementSupport
     }
 
     @Override
-    protected YangDataEffectiveStatement createEffective(final Current<String, YangDataStatement> stmt,
+    protected YangDataEffectiveStatement createEffective(final Current<YangDataName, YangDataStatement> stmt,
             final ImmutableList<? extends EffectiveStatement<?, ?>> substatements) {
         // RFC8040 page 80 requires that:
         //    It MUST contain data definition statements
index 93754121e382e4d09fea6b53bc63b4a4c58bc4cc..bf9ca28a3bbcb09e32ee43b124ce729c6c3ef100 100644 (file)
@@ -31,7 +31,7 @@ public class YT1338Test extends AbstractYangDataTest {
             .findModuleStatement(YangDataConstants.RFC8040_MODULE)
             .orElseThrow()
             .streamEffectiveSubstatements(YangDataEffectiveStatement.class)
-            .filter(stmt -> "yang-api".equals(stmt.argument()))
+            .filter(stmt -> YangDataStatementSupport.YANG_API.equals(stmt.argument()))
             .findAny()
             .orElseThrow()
             .findDataTreeNode(QName.create(YangDataConstants.RFC8040_MODULE, "restconf"))