Correct Context{Instance,Reference} statements 34/95734/1
authorRobert Varga <robert.varga@pantheon.tech>
Fri, 9 Apr 2021 13:20:19 +0000 (15:20 +0200)
committerRobert Varga <robert.varga@pantheon.tech>
Fri, 9 Apr 2021 20:12:25 +0000 (22:12 +0200)
context-instance and context-reference statements' argument is actually
a 'identifier-ref-arg-str' which points to a  much like the argument of
'base' in case of 'type identityref'.

Correct the argument definition and improve the definition of effective
statements to expose the referenced identity.

JIRA: YANGTOOLS-1196
Change-Id: I736df614f9d4c26e910ce78f8d6478a6735f3730
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
17 files changed:
yang/odlext-model-api/src/main/java/org/opendaylight/yangtools/odlext/model/api/ContextInstanceEffectiveStatement.java
yang/odlext-model-api/src/main/java/org/opendaylight/yangtools/odlext/model/api/ContextInstanceStatement.java
yang/odlext-model-api/src/main/java/org/opendaylight/yangtools/odlext/model/api/ContextReferenceEffectiveStatement.java
yang/odlext-model-api/src/main/java/org/opendaylight/yangtools/odlext/model/api/ContextReferenceStatement.java
yang/odlext-parser-support/src/main/java/org/opendaylight/yangtools/odlext/parser/AbstractIdentityAwareEffectiveStatement.java [new file with mode: 0644]
yang/odlext-parser-support/src/main/java/org/opendaylight/yangtools/odlext/parser/AbstractIdentityAwareStatementSupport.java [new file with mode: 0644]
yang/odlext-parser-support/src/main/java/org/opendaylight/yangtools/odlext/parser/ContextInstanceEffectiveStatementImpl.java
yang/odlext-parser-support/src/main/java/org/opendaylight/yangtools/odlext/parser/ContextInstanceStatementImpl.java
yang/odlext-parser-support/src/main/java/org/opendaylight/yangtools/odlext/parser/ContextInstanceStatementSupport.java
yang/odlext-parser-support/src/main/java/org/opendaylight/yangtools/odlext/parser/ContextReferenceEffectiveStatementImpl.java
yang/odlext-parser-support/src/main/java/org/opendaylight/yangtools/odlext/parser/ContextReferenceStatementImpl.java
yang/odlext-parser-support/src/main/java/org/opendaylight/yangtools/odlext/parser/ContextReferenceStatementSupport.java
yang/odlext-parser-support/src/test/java/org/opendaylight/yangtools/odlext/parser/Bug3874ExtensionTest.java
yang/odlext-parser-support/src/test/java/org/opendaylight/yangtools/odlext/parser/ContextReferenceTest.java [new file with mode: 0644]
yang/odlext-parser-support/src/test/resources/bug3874.yang [moved from yang/odlext-parser-support/src/test/resources/bugs/bug3874/foo.yang with 100% similarity]
yang/odlext-parser-support/src/test/resources/ctxref.yang [new file with mode: 0644]
yang/odlext-parser-support/src/test/resources/yang-ext.yang [moved from yang/odlext-parser-support/src/test/resources/bugs/bug3874/yang-ext.yang with 100% similarity]

index 3269b7a19075deadc7c15ed1235bf7e7827a4aa1..02a9aaf43f22ab2d7470f01f3575166820fda75a 100644 (file)
@@ -8,14 +8,23 @@
 package org.opendaylight.yangtools.odlext.model.api;
 
 import com.google.common.annotations.Beta;
+import org.eclipse.jdt.annotation.NonNull;
+import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
+import org.opendaylight.yangtools.yang.model.api.stmt.IdentityEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.UnknownEffectiveStatement;
 
 @Beta
-public interface ContextInstanceEffectiveStatement
-        extends UnknownEffectiveStatement<String, ContextInstanceStatement> {
+public interface ContextInstanceEffectiveStatement extends UnknownEffectiveStatement<QName, ContextInstanceStatement> {
     @Override
     default StatementDefinition statementDefinition() {
         return OpenDaylightExtensionsStatements.CONTEXT_INSTANCE;
     }
+
+    /**
+     * Return the {@link IdentityEffectiveStatement} identifying the {@code context type} of this instance.
+     *
+     * @return An {@link IdentityEffectiveStatement}.
+     */
+    @NonNull IdentityEffectiveStatement contextType();
 }
index 6031020e4780dea0f54767d8f864f1953393b6d5..34f087da273a24ab13a8ba39e34227db0ffcd358 100644 (file)
@@ -8,11 +8,12 @@
 package org.opendaylight.yangtools.odlext.model.api;
 
 import com.google.common.annotations.Beta;
+import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
 import org.opendaylight.yangtools.yang.model.api.stmt.UnknownStatement;
 
 @Beta
-public interface ContextInstanceStatement extends UnknownStatement<String> {
+public interface ContextInstanceStatement extends UnknownStatement<QName> {
     @Override
     default StatementDefinition statementDefinition() {
         return OpenDaylightExtensionsStatements.CONTEXT_INSTANCE;
index 363f521b13d37d4d944c224482f933e39a511aa1..0d6460f5f8a3dbb3afdd4f5257120001bac2aced 100644 (file)
@@ -8,14 +8,24 @@
 package org.opendaylight.yangtools.odlext.model.api;
 
 import com.google.common.annotations.Beta;
+import org.eclipse.jdt.annotation.NonNull;
+import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
+import org.opendaylight.yangtools.yang.model.api.stmt.IdentityEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.UnknownEffectiveStatement;
 
 @Beta
 public interface ContextReferenceEffectiveStatement
-        extends UnknownEffectiveStatement<String, ContextReferenceStatement> {
+        extends UnknownEffectiveStatement<QName, ContextReferenceStatement> {
     @Override
     default StatementDefinition statementDefinition() {
         return OpenDaylightExtensionsStatements.CONTEXT_REFERENCE;
     }
+
+    /**
+     * Return the {@link IdentityEffectiveStatement} identifying the {@code context type} of this reference.
+     *
+     * @return An {@link IdentityEffectiveStatement}.
+     */
+    @NonNull IdentityEffectiveStatement contextType();
 }
index 16ce32c5066926c4b92d25087f3bc131b196af99..99f172c5f148b3bfae82162517db1bc868ad9e8d 100644 (file)
@@ -8,11 +8,12 @@
 package org.opendaylight.yangtools.odlext.model.api;
 
 import com.google.common.annotations.Beta;
+import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
 import org.opendaylight.yangtools.yang.model.api.stmt.UnknownStatement;
 
 @Beta
-public interface ContextReferenceStatement extends UnknownStatement<String> {
+public interface ContextReferenceStatement extends UnknownStatement<QName> {
     @Override
     default StatementDefinition statementDefinition() {
         return OpenDaylightExtensionsStatements.CONTEXT_REFERENCE;
diff --git a/yang/odlext-parser-support/src/main/java/org/opendaylight/yangtools/odlext/parser/AbstractIdentityAwareEffectiveStatement.java b/yang/odlext-parser-support/src/main/java/org/opendaylight/yangtools/odlext/parser/AbstractIdentityAwareEffectiveStatement.java
new file mode 100644 (file)
index 0000000..3e0b72a
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * 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.odlext.parser;
+
+import static java.util.Objects.requireNonNull;
+
+import com.google.common.collect.ImmutableList;
+import org.eclipse.jdt.annotation.NonNull;
+import org.opendaylight.yangtools.yang.common.QName;
+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.IdentityEffectiveStatement;
+import org.opendaylight.yangtools.yang.model.spi.meta.AbstractDeclaredEffectiveStatement.DefaultArgument.WithSubstatements;
+
+abstract class AbstractIdentityAwareEffectiveStatement<D extends DeclaredStatement<QName>>
+        extends WithSubstatements<QName, D> {
+    private final @NonNull IdentityEffectiveStatement identity;
+
+    AbstractIdentityAwareEffectiveStatement(final D declared, final IdentityEffectiveStatement identity,
+            final ImmutableList<? extends EffectiveStatement<?, ?>> substatements) {
+        super(declared, substatements);
+        this.identity = requireNonNull(identity);
+    }
+
+    final @NonNull IdentityEffectiveStatement identity() {
+        return identity;
+    }
+}
diff --git a/yang/odlext-parser-support/src/main/java/org/opendaylight/yangtools/odlext/parser/AbstractIdentityAwareStatementSupport.java b/yang/odlext-parser-support/src/main/java/org/opendaylight/yangtools/odlext/parser/AbstractIdentityAwareStatementSupport.java
new file mode 100644 (file)
index 0000000..657ac08
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2021 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.odlext.parser;
+
+import static com.google.common.base.Verify.verifyNotNull;
+
+import com.google.common.collect.ImmutableList;
+import java.util.Collection;
+import org.eclipse.jdt.annotation.NonNull;
+import org.opendaylight.yangtools.yang.common.QName;
+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.meta.StatementDefinition;
+import org.opendaylight.yangtools.yang.model.api.stmt.IdentityEffectiveStatement;
+import org.opendaylight.yangtools.yang.parser.spi.IdentityNamespace;
+import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractStatementSupport;
+import org.opendaylight.yangtools.yang.parser.spi.meta.EffectiveStmtCtx.Current;
+import org.opendaylight.yangtools.yang.parser.spi.meta.InferenceException;
+import org.opendaylight.yangtools.yang.parser.spi.meta.ModelActionBuilder;
+import org.opendaylight.yangtools.yang.parser.spi.meta.ModelActionBuilder.InferenceAction;
+import org.opendaylight.yangtools.yang.parser.spi.meta.ModelActionBuilder.InferenceContext;
+import org.opendaylight.yangtools.yang.parser.spi.meta.ModelActionBuilder.Prerequisite;
+import org.opendaylight.yangtools.yang.parser.spi.meta.ModelProcessingPhase;
+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;
+
+abstract class AbstractIdentityAwareStatementSupport<D extends DeclaredStatement<QName>,
+        E extends EffectiveStatement<QName, D>> extends AbstractStatementSupport<QName, D, E> {
+    private final SubstatementValidator validator;
+
+    AbstractIdentityAwareStatementSupport(final StatementDefinition publicDefinition) {
+        super(publicDefinition, StatementPolicy.exactReplica());
+        validator = SubstatementValidator.builder(publicDefinition).build();
+    }
+
+    @Override
+    public final QName parseArgumentValue(final StmtContext<?, ?, ?> ctx, final String value) {
+        return StmtContextUtils.parseNodeIdentifier(ctx, value);
+    }
+
+    @Override
+    public void onStatementDefinitionDeclared(final Mutable<QName, D, E> stmt) {
+        final ModelActionBuilder action = stmt.newInferenceAction(ModelProcessingPhase.EFFECTIVE_MODEL);
+        action.requiresCtx(stmt, IdentityNamespace.class, stmt.getArgument(), ModelProcessingPhase.EFFECTIVE_MODEL);
+
+        action.apply(new InferenceAction() {
+            @Override
+            public void apply(final InferenceContext ctx) {
+                // No-op, we just want to ensure the statement is specified
+            }
+
+            @Override
+            public void prerequisiteFailed(final Collection<? extends Prerequisite<?>> failed) {
+                throw new InferenceException(stmt, "Unable to resolve identity %s", stmt.argument());
+            }
+        });
+    }
+
+    @Override
+    protected final SubstatementValidator getSubstatementValidator() {
+        return validator;
+    }
+
+    @Override
+    protected final E createEffective(final Current<QName, D> stmt,
+            final ImmutableList<? extends EffectiveStatement<?, ?>> substatements) {
+        final QName qname = stmt.getArgument();
+        final StmtContext<?, ?, IdentityEffectiveStatement> identityCtx =
+            verifyNotNull(stmt.getFromNamespace(IdentityNamespace.class, qname), "Failed to find identity %s", qname);
+        return createEffective(stmt.declared(), identityCtx.buildEffective(), substatements);
+    }
+
+    abstract @NonNull E createEffective(@NonNull D declared, @NonNull IdentityEffectiveStatement identity,
+        ImmutableList<? extends EffectiveStatement<?, ?>> substatements);
+}
index d191f30d0be8bbd449a63cabf5f3a89508174938..8df8677f2294b19d2a997808a994a58a87d8bc4e 100644 (file)
@@ -11,12 +11,19 @@ import com.google.common.collect.ImmutableList;
 import org.opendaylight.yangtools.odlext.model.api.ContextInstanceEffectiveStatement;
 import org.opendaylight.yangtools.odlext.model.api.ContextInstanceStatement;
 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
-import org.opendaylight.yangtools.yang.model.spi.meta.AbstractDeclaredEffectiveStatement.DefaultArgument.WithSubstatements;
+import org.opendaylight.yangtools.yang.model.api.stmt.IdentityEffectiveStatement;
 
-final class ContextInstanceEffectiveStatementImpl extends WithSubstatements<String, ContextInstanceStatement>
+final class ContextInstanceEffectiveStatementImpl
+        extends AbstractIdentityAwareEffectiveStatement<ContextInstanceStatement>
         implements ContextInstanceEffectiveStatement {
     ContextInstanceEffectiveStatementImpl(final ContextInstanceStatement declared,
+            final IdentityEffectiveStatement identity,
             final ImmutableList<? extends EffectiveStatement<?, ?>> substatements) {
-        super(declared, substatements);
+        super(declared, identity, substatements);
+    }
+
+    @Override
+    public IdentityEffectiveStatement contextType() {
+        return identity();
     }
 }
index b64360537be5bf291870f0ee91ed37693c05caa5..700ae7bc3beb8f0c75e5894442ac2c02466cd7ce 100644 (file)
@@ -9,12 +9,13 @@ package org.opendaylight.yangtools.odlext.parser;
 
 import com.google.common.collect.ImmutableList;
 import org.opendaylight.yangtools.odlext.model.api.ContextInstanceStatement;
+import org.opendaylight.yangtools.yang.common.QName;
 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;
 
-final class ContextInstanceStatementImpl extends WithSubstatements implements ContextInstanceStatement {
-    ContextInstanceStatementImpl(final String argument,
+final class ContextInstanceStatementImpl extends WithSubstatements<QName> implements ContextInstanceStatement {
+    ContextInstanceStatementImpl(final String rawArgument, final QName argument,
             final ImmutableList<? extends DeclaredStatement<?>> substatements) {
-        super(argument, substatements);
+        super(rawArgument, argument, substatements);
     }
 }
index 526b71f1e0f44d30bd3dd45e469f95e0e3b3c34b..7c10f5b12775d3c4b07ae7626a98b784d3d2f4e2 100644 (file)
@@ -13,39 +13,31 @@ import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.yangtools.odlext.model.api.ContextInstanceEffectiveStatement;
 import org.opendaylight.yangtools.odlext.model.api.ContextInstanceStatement;
 import org.opendaylight.yangtools.odlext.model.api.OpenDaylightExtensionsStatements;
+import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
-import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractStringStatementSupport;
-import org.opendaylight.yangtools.yang.parser.spi.meta.EffectiveStmtCtx.Current;
+import org.opendaylight.yangtools.yang.model.api.stmt.IdentityEffectiveStatement;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
-import org.opendaylight.yangtools.yang.parser.spi.meta.SubstatementValidator;
 
 @Beta
 public final class ContextInstanceStatementSupport
-        extends AbstractStringStatementSupport<ContextInstanceStatement, ContextInstanceEffectiveStatement> {
+        extends AbstractIdentityAwareStatementSupport<ContextInstanceStatement, ContextInstanceEffectiveStatement> {
     public static final @NonNull ContextInstanceStatementSupport INSTANCE = new ContextInstanceStatementSupport();
 
-    private static final SubstatementValidator VALIDATOR =
-        SubstatementValidator.builder(OpenDaylightExtensionsStatements.CONTEXT_INSTANCE).build();
-
     private ContextInstanceStatementSupport() {
-        super(OpenDaylightExtensionsStatements.CONTEXT_INSTANCE, StatementPolicy.contextIndependent());
-    }
-
-    @Override
-    protected SubstatementValidator getSubstatementValidator() {
-        return VALIDATOR;
+        super(OpenDaylightExtensionsStatements.CONTEXT_INSTANCE);
     }
 
     @Override
-    protected ContextInstanceStatement createDeclared(final StmtContext<String, ContextInstanceStatement, ?> ctx,
+    protected ContextInstanceStatement createDeclared(final StmtContext<QName, ContextInstanceStatement, ?> ctx,
             final ImmutableList<? extends DeclaredStatement<?>> substatements) {
-        return new ContextInstanceStatementImpl(ctx.getArgument(), substatements);
+        return new ContextInstanceStatementImpl(ctx.getRawArgument(), ctx.getArgument(), substatements);
     }
 
     @Override
-    protected ContextInstanceEffectiveStatement createEffective(final Current<String, ContextInstanceStatement> stmt,
+    ContextInstanceEffectiveStatement createEffective(final ContextInstanceStatement declared,
+            final IdentityEffectiveStatement identity,
             final ImmutableList<? extends EffectiveStatement<?, ?>> substatements) {
-        return new ContextInstanceEffectiveStatementImpl(stmt.declared(), substatements);
+        return new ContextInstanceEffectiveStatementImpl(declared, identity, substatements);
     }
 }
index 5557ede7cb5658852a6d4c3bef85f32f21bfef71..5009f1bac4e53316f14e5dbd1260225619806355 100644 (file)
@@ -11,12 +11,19 @@ import com.google.common.collect.ImmutableList;
 import org.opendaylight.yangtools.odlext.model.api.ContextReferenceEffectiveStatement;
 import org.opendaylight.yangtools.odlext.model.api.ContextReferenceStatement;
 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
-import org.opendaylight.yangtools.yang.model.spi.meta.AbstractDeclaredEffectiveStatement.DefaultArgument.WithSubstatements;
+import org.opendaylight.yangtools.yang.model.api.stmt.IdentityEffectiveStatement;
 
-final class ContextReferenceEffectiveStatementImpl extends WithSubstatements<String, ContextReferenceStatement>
+final class ContextReferenceEffectiveStatementImpl
+        extends AbstractIdentityAwareEffectiveStatement<ContextReferenceStatement>
         implements ContextReferenceEffectiveStatement {
     ContextReferenceEffectiveStatementImpl(final ContextReferenceStatement declared,
+            final IdentityEffectiveStatement identity,
             final ImmutableList<? extends EffectiveStatement<?, ?>> substatements) {
-        super(declared, substatements);
+        super(declared, identity, substatements);
+    }
+
+    @Override
+    public IdentityEffectiveStatement contextType() {
+        return identity();
     }
 }
index 76ecb9a82dbe0e9d2f644e25e58808896a0ee3fb..d68511dd9283e245671aa3c095510a8cea9d63fd 100644 (file)
@@ -9,12 +9,13 @@ package org.opendaylight.yangtools.odlext.parser;
 
 import com.google.common.collect.ImmutableList;
 import org.opendaylight.yangtools.odlext.model.api.ContextReferenceStatement;
+import org.opendaylight.yangtools.yang.common.QName;
 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;
 
-final class ContextReferenceStatementImpl extends WithSubstatements implements ContextReferenceStatement {
-    ContextReferenceStatementImpl(final String argument,
+final class ContextReferenceStatementImpl extends WithSubstatements<QName> implements ContextReferenceStatement {
+    ContextReferenceStatementImpl(final String rawArgument, final QName argument,
             final ImmutableList<? extends DeclaredStatement<?>> substatements) {
-        super(argument, substatements);
+        super(rawArgument, argument, substatements);
     }
 }
index 67a5d870a7c7c2ec547e4cdc07f133d0193ec297..f7fc4dc870493abf2d26bf526efd20bf5b0601e7 100644 (file)
@@ -13,39 +13,31 @@ import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.yangtools.odlext.model.api.ContextReferenceEffectiveStatement;
 import org.opendaylight.yangtools.odlext.model.api.ContextReferenceStatement;
 import org.opendaylight.yangtools.odlext.model.api.OpenDaylightExtensionsStatements;
+import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
-import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractStringStatementSupport;
-import org.opendaylight.yangtools.yang.parser.spi.meta.EffectiveStmtCtx.Current;
+import org.opendaylight.yangtools.yang.model.api.stmt.IdentityEffectiveStatement;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
-import org.opendaylight.yangtools.yang.parser.spi.meta.SubstatementValidator;
 
 @Beta
 public final class ContextReferenceStatementSupport
-        extends AbstractStringStatementSupport<ContextReferenceStatement, ContextReferenceEffectiveStatement> {
+        extends AbstractIdentityAwareStatementSupport<ContextReferenceStatement, ContextReferenceEffectiveStatement> {
     public static final @NonNull ContextReferenceStatementSupport INSTANCE = new ContextReferenceStatementSupport();
 
-    private static final SubstatementValidator VALIDATOR =
-        SubstatementValidator.builder(OpenDaylightExtensionsStatements.CONTEXT_REFERENCE).build();
-
     private ContextReferenceStatementSupport() {
-        super(OpenDaylightExtensionsStatements.CONTEXT_REFERENCE, StatementPolicy.contextIndependent());
-    }
-
-    @Override
-    protected SubstatementValidator getSubstatementValidator() {
-        return VALIDATOR;
+        super(OpenDaylightExtensionsStatements.CONTEXT_REFERENCE);
     }
 
     @Override
-    protected ContextReferenceStatement createDeclared(final StmtContext<String, ContextReferenceStatement, ?> ctx,
+    protected ContextReferenceStatement createDeclared(final StmtContext<QName, ContextReferenceStatement, ?> ctx,
             final ImmutableList<? extends DeclaredStatement<?>> substatements) {
-        return new ContextReferenceStatementImpl(ctx.getArgument(), substatements);
+        return new ContextReferenceStatementImpl(ctx.rawArgument(), ctx.getArgument(), substatements);
     }
 
     @Override
-    protected ContextReferenceEffectiveStatement createEffective(final Current<String, ContextReferenceStatement> stmt,
+    ContextReferenceEffectiveStatement createEffective(final ContextReferenceStatement declared,
+            final IdentityEffectiveStatement identity,
             final ImmutableList<? extends EffectiveStatement<?, ?>> substatements) {
-        return new ContextReferenceEffectiveStatementImpl(stmt.declared(), substatements);
+        return new ContextReferenceEffectiveStatementImpl(declared, identity, substatements);
     }
 }
index af0a3b19d1a3e8027c655bf2df6cc55b9b3ab18e..162558414263264c80ab3163d228da4c5e519a16 100644 (file)
@@ -38,10 +38,10 @@ public class Bug3874ExtensionTest {
     @BeforeClass
     public static void createReactor() {
         reactor = RFC7950Reactors.vanillaReactorBuilder()
-                .addStatementSupport(ModelProcessingPhase.FULL_DECLARATION,
-                    AnyxmlSchemaLocationStatementSupport.getInstance())
-                .addNamespaceSupport(ModelProcessingPhase.FULL_DECLARATION, AnyxmlSchemaLocationNamespace.BEHAVIOUR)
-                .build();
+            .addStatementSupport(ModelProcessingPhase.FULL_DECLARATION,
+                AnyxmlSchemaLocationStatementSupport.getInstance())
+            .addNamespaceSupport(ModelProcessingPhase.FULL_DECLARATION, AnyxmlSchemaLocationNamespace.BEHAVIOUR)
+            .build();
     }
 
     @AfterClass
@@ -52,10 +52,9 @@ public class Bug3874ExtensionTest {
     @Test
     public void test() throws Exception {
         SchemaContext context = reactor.newBuild()
-                .addSource(YangStatementStreamSource.create(YangTextSchemaSource.forResource("/bugs/bug3874/foo.yang")))
-                .addSource(YangStatementStreamSource.create(
-                    YangTextSchemaSource.forResource("/bugs/bug3874/yang-ext.yang")))
-                .buildEffective();
+            .addSource(YangStatementStreamSource.create(YangTextSchemaSource.forResource("/yang-ext.yang")))
+            .addSource(YangStatementStreamSource.create(YangTextSchemaSource.forResource("/bug3874.yang")))
+            .buildEffective();
 
         QNameModule foo = QNameModule.create(XMLNamespace.of("foo"));
         QName myContainer2QName = QName.create(foo, "my-container-2");
@@ -74,7 +73,7 @@ public class Bug3874ExtensionTest {
         UnknownSchemaNode next = unknownSchemaNodes.iterator().next();
         assertThat(next, instanceOf(AnyxmlSchemaLocationEffectiveStatementImpl.class));
         AnyxmlSchemaLocationEffectiveStatementImpl anyxmlSchemaLocationUnknownNode =
-                (AnyxmlSchemaLocationEffectiveStatementImpl) next;
+            (AnyxmlSchemaLocationEffectiveStatementImpl) next;
         assertEquals(Absolute.of(myContainer2QName), anyxmlSchemaLocationUnknownNode.argument());
         assertEquals(OpenDaylightExtensionsStatements.ANYXML_SCHEMA_LOCATION.getStatementName(),
             anyxmlSchemaLocationUnknownNode.getNodeType());
diff --git a/yang/odlext-parser-support/src/test/java/org/opendaylight/yangtools/odlext/parser/ContextReferenceTest.java b/yang/odlext-parser-support/src/test/java/org/opendaylight/yangtools/odlext/parser/ContextReferenceTest.java
new file mode 100644 (file)
index 0000000..611459a
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. 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.odlext.parser;
+
+import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertSame;
+
+import java.util.List;
+import java.util.stream.Collectors;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.opendaylight.yangtools.odlext.model.api.ContextInstanceEffectiveStatement;
+import org.opendaylight.yangtools.odlext.model.api.ContextReferenceEffectiveStatement;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.QNameModule;
+import org.opendaylight.yangtools.yang.common.XMLNamespace;
+import org.opendaylight.yangtools.yang.model.api.stmt.DataTreeEffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.GroupingEffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.LeafEffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.LeafListEffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.ListEffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.ModuleEffectiveStatement;
+import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
+import org.opendaylight.yangtools.yang.parser.rfc7950.reactor.RFC7950Reactors;
+import org.opendaylight.yangtools.yang.parser.rfc7950.repo.YangStatementStreamSource;
+import org.opendaylight.yangtools.yang.parser.spi.meta.ModelProcessingPhase;
+import org.opendaylight.yangtools.yang.parser.stmt.reactor.CrossSourceStatementReactor;
+
+public class ContextReferenceTest {
+    private static final QNameModule FOO = QNameModule.create(XMLNamespace.of("foo"));
+    private static final QName LEAF_TYPE = QName.create(FOO, "leaf-type");
+    private static final QName LIST_TYPE = QName.create(FOO, "list-type");
+
+    private static CrossSourceStatementReactor reactor;
+
+    @BeforeClass
+    public static void createReactor() {
+        reactor = RFC7950Reactors.vanillaReactorBuilder()
+            .addStatementSupport(ModelProcessingPhase.FULL_DECLARATION, ContextInstanceStatementSupport.INSTANCE)
+            .addStatementSupport(ModelProcessingPhase.FULL_DECLARATION, ContextReferenceStatementSupport.INSTANCE)
+            .build();
+    }
+
+    @AfterClass
+    public static void freeReactor() {
+        reactor = null;
+    }
+
+    @Test
+    public void test() throws Exception {
+        final ModuleEffectiveStatement foo = reactor.newBuild()
+            .addSource(YangStatementStreamSource.create(YangTextSchemaSource.forResource("/yang-ext.yang")))
+            .addSource(YangStatementStreamSource.create(YangTextSchemaSource.forResource("/ctxref.yang")))
+            .buildEffective()
+            .getModuleStatements()
+            .get(FOO);
+
+        final DataTreeEffectiveStatement<?> list = foo.findDataTreeNode(QName.create(FOO, "list")).orElseThrow();
+        assertThat(list, instanceOf(ListEffectiveStatement.class));
+
+        final ContextInstanceEffectiveStatement listType = list
+            .findFirstEffectiveSubstatement(ContextInstanceEffectiveStatement.class).orElseThrow();
+        assertEquals(LIST_TYPE, listType.argument());
+        assertEquals(LIST_TYPE, listType.contextType().argument());
+
+        final ContextInstanceEffectiveStatement leafType = list
+            .findFirstEffectiveSubstatement(LeafEffectiveStatement.class).orElseThrow()
+            .findFirstEffectiveSubstatement(ContextInstanceEffectiveStatement.class).orElseThrow();
+        assertEquals(LEAF_TYPE, leafType.argument());
+        assertEquals(LEAF_TYPE, leafType.contextType().argument());
+
+        final List<GroupingEffectiveStatement> groupings = foo
+            .streamEffectiveSubstatements(GroupingEffectiveStatement.class).collect(Collectors.toList());
+        assertEquals(2, groupings.size());
+
+        final ContextReferenceEffectiveStatement listRef = groupings.get(1)
+            .findFirstEffectiveSubstatement(LeafEffectiveStatement.class).orElseThrow()
+            .findFirstEffectiveSubstatement(ContextReferenceEffectiveStatement.class).orElseThrow();
+        assertEquals(LIST_TYPE, listType.argument());
+        assertSame(listType.contextType(), listRef.contextType());
+
+        final ContextReferenceEffectiveStatement leafRef = groupings.get(0)
+            .findFirstEffectiveSubstatement(LeafListEffectiveStatement.class).orElseThrow()
+            .findFirstEffectiveSubstatement(ContextReferenceEffectiveStatement.class).orElseThrow();
+        assertEquals(LEAF_TYPE, leafType.argument());
+        assertSame(leafType.contextType(), leafRef.contextType());
+    }
+}
diff --git a/yang/odlext-parser-support/src/test/resources/ctxref.yang b/yang/odlext-parser-support/src/test/resources/ctxref.yang
new file mode 100644 (file)
index 0000000..4ba8eb3
--- /dev/null
@@ -0,0 +1,37 @@
+module foo {
+  namespace "foo";
+  prefix foo;
+
+  import yang-ext {
+    prefix ext;
+  }
+
+  list list {
+    key key;
+
+    leaf key {
+      type string;
+      ext:context-instance leaf-type;
+    }
+
+    ext:context-instance list-type;
+  }
+
+  grouping leaf-ref {
+    leaf-list leaf-ref {
+      type instance-identifier;
+      ext:context-reference leaf-type;
+    }
+  }
+
+  grouping list-ref {
+    leaf list-ref {
+      type instance-identifier;
+      ext:context-reference list-type;
+    }
+  }
+
+  identity leaf-type;
+
+  identity list-type;
+}