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();
}
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;
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();
}
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;
--- /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.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;
+ }
+}
--- /dev/null
+/*
+ * 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);
+}
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();
}
}
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);
}
}
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);
}
}
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();
}
}
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);
}
}
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);
}
}
@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
@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");
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());
--- /dev/null
+/*
+ * 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());
+ }
+}
--- /dev/null
+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;
+}