import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace;
import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
+import org.opendaylight.yangtools.yang.parser.spi.GroupingNamespace;
import org.opendaylight.yangtools.yang.parser.spi.SchemaTreeNamespace;
import org.opendaylight.yangtools.yang.parser.spi.meta.ModelProcessingPhase;
import org.opendaylight.yangtools.yang.parser.spi.meta.MutableStatement;
private static final Logger LOG = LoggerFactory.getLogger(RootStatementContext.class);
// These namespaces are well-known and not needed after the root is cleaned up
private static final Map<Class<?>, SweptNamespace> SWEPT_NAMESPACES = ImmutableMap.of(
- // FIXME: YANGTOOLS-1197: sweep GroupingNamespace
- // GroupingNamespace.class, new SweptNamespace(GroupingNamespace.class),
+ GroupingNamespace.class, new SweptNamespace(GroupingNamespace.class),
// FIXME: YANGTOOLS-1198: sweep TypeNamespace
// TypeNamespace.class, new SweptNamespace(TypeNamespace.class),
SchemaTreeNamespace.class, new SweptNamespace(SchemaTreeNamespace.class));
import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.typedef.TypedefStatementSupport;
import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.unique.UniqueStatementSupport;
import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.units.UnitsStatementSupport;
+import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.uses.SourceGroupingNamespace;
import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.uses.UsesStatementSupport;
import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.value.ValueStatementSupport;
import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.when.WhenStatementSupport;
.addSupport(FeatureNamespace.BEHAVIOUR)
.addVersionSpecificSupport(VERSION_1, IfFeatureStatementRFC6020Support.getInstance())
.addVersionSpecificSupport(VERSION_1_1, IfFeatureStatementRFC7950Support.getInstance())
- .addSupport(UsesStatementSupport.getInstance())
.addSupport(GroupingNamespace.BEHAVIOUR)
+ .addSupport(SourceGroupingNamespace.BEHAVIOUR)
+ .addSupport(UsesStatementSupport.getInstance())
.addSupport(ErrorMessageStatementSupport.getInstance())
.addSupport(ErrorAppTagStatementSupport.getInstance())
.addVersionSpecificSupport(VERSION_1, LeafListStatementRFC6020Support.getInstance())
package org.opendaylight.yangtools.yang.parser.rfc7950.stmt.grouping;
import com.google.common.collect.ImmutableList;
+import java.util.Collection;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.model.api.YangStmtMapping;
import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.SubstatementIndexingException;
import org.opendaylight.yangtools.yang.parser.spi.GroupingNamespace;
import org.opendaylight.yangtools.yang.parser.spi.meta.EffectiveStmtCtx.Current;
+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;
final Mutable<QName, GroupingStatement, GroupingEffectiveStatement> stmt) {
super.onFullDefinitionDeclared(stmt);
- if (stmt != null) {
- final Mutable<?, ?, ?> parent = stmt.getParentContext();
- if (parent != null) {
- // Shadowing check: make sure we do not trample on pre-existing definitions. This catches sibling
- // declarations and parent declarations which have already been declared.
- checkConflict(parent, stmt);
- parent.addContext(GroupingNamespace.class, stmt.getArgument(), stmt);
+ final Mutable<?, ?, ?> parent = stmt.getParentContext();
+ if (parent != null) {
+ // Shadowing check: make sure we do not trample on pre-existing definitions. This catches sibling
+ // declarations and parent declarations which have already been declared.
+ checkConflict(parent, stmt);
+ parent.addContext(GroupingNamespace.class, stmt.getArgument(), stmt);
+
+ final StmtContext<?, ?, ?> grandParent = parent.getParentContext();
+ if (grandParent != null) {
+ // Shadowing check: make sure grandparent does not see a conflicting definition. This is required to
+ // ensure that a grouping in child scope does not shadow a grouping in parent scope which occurs later
+ // in the text. For that check we need the full declaration of our model.
+ final ModelActionBuilder action = stmt.newInferenceAction(ModelProcessingPhase.FULL_DECLARATION);
+ action.requiresCtx(grandParent.getRoot(), ModelProcessingPhase.FULL_DECLARATION);
+ action.apply(new InferenceAction() {
+ @Override
+ public void apply(final InferenceContext ctx) {
+ checkConflict(grandParent, stmt);
+ }
+
+ @Override
+ public void prerequisiteFailed(final Collection<? extends Prerequisite<?>> failed) {
+ // No-op
+ }
+ });
}
}
}
@Override
protected final GroupingStatement createDeclared(final StmtContext<QName, GroupingStatement, ?> ctx,
final ImmutableList<? extends DeclaredStatement<?>> substatements) {
- checkDeclaredConflict(ctx);
return new RegularGroupingStatement(ctx.getArgument(), substatements);
}
@Override
protected final GroupingStatement createEmptyDeclared(final StmtContext<QName, GroupingStatement, ?> ctx) {
- checkDeclaredConflict(ctx);
return new EmptyGroupingStatement(ctx.getArgument());
}
}
}
- private static void checkDeclaredConflict(final StmtContext<QName, ?, ?> ctx) {
- // Shadowing check: make sure grandparent does not see a conflicting definition. This is required to ensure
- // that a grouping in child scope does not shadow a grouping in parent scope which occurs later in the text.
- final StmtContext<?, ?, ?> parent = ctx.getParentContext();
- if (parent != null) {
- final StmtContext<?, ?, ?> grandParent = parent.getParentContext();
- if (grandParent != null) {
- checkConflict(grandParent, ctx);
- }
- }
- }
-
private static void checkConflict(final StmtContext<?, ?, ?> parent, final StmtContext<QName, ?, ?> stmt) {
final QName arg = stmt.getArgument();
final StmtContext<?, ?, ?> existing = parent.getFromNamespace(GroupingNamespace.class, arg);
--- /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.yang.parser.rfc7950.stmt.uses;
+
+import com.google.common.annotations.Beta;
+import org.eclipse.jdt.annotation.NonNull;
+import org.opendaylight.yangtools.yang.common.Empty;
+import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace;
+import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour;
+import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
+
+@Beta
+public interface SourceGroupingNamespace extends IdentifierNamespace<Empty, StmtContext<?, ?, ?>> {
+ NamespaceBehaviour<Empty, StmtContext<?, ?, ?>, @NonNull SourceGroupingNamespace> BEHAVIOUR =
+ NamespaceBehaviour.statementLocal(SourceGroupingNamespace.class);
+}
*/
package org.opendaylight.yangtools.yang.parser.rfc7950.stmt.uses;
+import static com.google.common.base.Verify.verifyNotNull;
+
import com.google.common.base.Verify;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import java.util.Map;
import java.util.Optional;
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.common.QNameModule;
import org.opendaylight.yangtools.yang.common.YangVersion;
copyFromSourceToTarget(sourceGrpStmtCtx, targetNodeStmtCtx, usesNode);
resolveUsesNode(usesNode, targetNodeStmtCtx);
StmtContextUtils.validateIfFeatureAndWhenOnListKeys(usesNode);
+ usesNode.addToNs(SourceGroupingNamespace.class, Empty.getInstance(), sourceGrpStmtCtx);
}
@Override
@Override
protected UsesEffectiveStatement createEffective(final Current<QName, UsesStatement> stmt,
final ImmutableList<? extends EffectiveStatement<?, ?>> substatements) {
- final GroupingDefinition sourceGrouping = getSourceGrouping(stmt);
+ final GroupingDefinition sourceGrouping = (GroupingDefinition)
+ verifyNotNull(stmt.getFromNamespace(SourceGroupingNamespace.class, Empty.getInstance())).buildEffective();
final int flags = historyAndStatusFlags(stmt.history(), substatements);
final QName argument = stmt.getArgument();
final UsesStatement declared = stmt.declared();
return ImmutableMap.copyOf(refines);
}
- private static GroupingDefinition getSourceGrouping(final Current<QName, ?> stmt) {
- // FIXME: YANGTOOLS-1197: we have this lookup in inference action, just store a replica in local namespace
- // during apply and pick it up when we build the statement
- return (GroupingDefinition) stmt.getFromNamespace(GroupingNamespace.class, stmt.getArgument()).buildEffective();
- }
-
/**
* Copy statements from a grouping to a target node.
*