import java.util.Collection;
import java.util.Objects;
import java.util.Optional;
+import org.opendaylight.yangtools.yang.common.Empty;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.model.api.YangStmtMapping;
import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
private static final Logger LOG = LoggerFactory.getLogger(AugmentInferenceAction.class);
private static final ImmutableSet<YangStmtMapping> NOCOPY_DEF_SET = ImmutableSet.of(YangStmtMapping.USES,
YangStmtMapping.WHEN, YangStmtMapping.DESCRIPTION, YangStmtMapping.REFERENCE, YangStmtMapping.STATUS);
- private static final ImmutableSet<YangStmtMapping> REUSED_DEF_SET = ImmutableSet.of(YangStmtMapping.TYPEDEF);
private final Mutable<SchemaNodeIdentifier, AugmentStatement, AugmentEffectiveStatement> augmentNode;
private final Prerequisite<Mutable<?, ?, EffectiveStatement<?, ?>>> target;
// We are targeting a context which is creating implicit nodes. In order to keep things consistent,
// we will need to circle back when creating effective statements.
if (augmentTargetCtx.hasImplicitParentSupport()) {
- augmentNode.addToNs(AugmentImplicitHandlingNamespace.class, augmentNode, augmentTargetCtx);
+ augmentNode.addToNs(AugmentImplicitHandlingNamespace.class, Empty.getInstance(), augmentTargetCtx);
}
- final StatementContextBase<?, ?, ?> augmentSourceCtx = (StatementContextBase<?, ?, ?>) augmentNode;
// FIXME: this is a workaround for models which augment a node which is added via an extension
// which we do not handle. This needs to be reworked in terms of unknown schema nodes.
try {
- copyFromSourceToTarget(augmentSourceCtx, augmentTargetCtx);
- augmentTargetCtx.addEffectiveSubstatement(augmentSourceCtx);
+ copyFromSourceToTarget((StatementContextBase<?, ?, ?>) augmentNode, augmentTargetCtx);
+ augmentTargetCtx.addEffectiveSubstatement(augmentNode.replicaAsChildOf(augmentTargetCtx));
} catch (final SourceException e) {
LOG.warn("Failed to add augmentation {} defined at {}", augmentTargetCtx.sourceReference(),
- augmentSourceCtx.sourceReference(), e);
+ augmentNode.sourceReference(), e);
}
}
}
}
- throw new InferenceException(augmentNode.sourceReference(), "Augment target '%s' not found",
- augmentNode.argument());
+ throw new InferenceException(augmentNode, "Augment target '%s' not found", augmentNode.argument());
}
private void copyFromSourceToTarget(final StatementContextBase<?, ?, ?> sourceCtx,
final boolean skipCheckOfMandatoryNodes, final boolean unsupported) {
// We always copy statements, but if either the source statement or the augmentation which causes it are not
// supported to build we also mark the target as such.
- if (needToCopyByAugment(original)) {
+ if (!NOCOPY_DEF_SET.contains(original.publicDefinition())) {
validateNodeCanBeCopiedByAugment(original, target, typeOfCopy, skipCheckOfMandatoryNodes);
final Mutable<?, ?, ?> copy = target.childCopyOf(original, typeOfCopy);
copy.setIsSupportedToBuildEffective(false);
}
buffer.add(copy);
- } else if (isReusedByAugment(original) && !unsupported) {
- buffer.add(original);
+ } else if (!unsupported && original.publicDefinition() == YangStmtMapping.TYPEDEF) {
+ buffer.add(original.replicaAsChildOf(target));
}
}
if (sourceCtx.producesDeclared(DataDefinitionStatement.class)) {
for (final StmtContext<?, ?, ?> subStatement : targetCtx.allSubstatements()) {
if (subStatement.producesDeclared(DataDefinitionStatement.class)) {
- InferenceException.throwIf(Objects.equals(sourceCtx.argument(), subStatement.argument()),
- sourceCtx.sourceReference(),
+ InferenceException.throwIf(Objects.equals(sourceCtx.argument(), subStatement.argument()), sourceCtx,
"An augment cannot add node named '%s' because this name is already used in target",
sourceCtx.rawArgument());
}
sourceCtx.allSubstatementsStream().forEach(AugmentInferenceAction::checkForMandatoryNodes);
}
- InferenceException.throwIf(StmtContextUtils.isMandatoryNode(sourceCtx), sourceCtx.sourceReference(),
+ InferenceException.throwIf(StmtContextUtils.isMandatoryNode(sourceCtx), sourceCtx,
"An augment cannot add node '%s' because it is mandatory and in module different than target",
sourceCtx.rawArgument());
}
// This could be an augmentation stacked on top of a previous augmentation from the same module, which is
// conditional -- in which case we do not run further checks
- if (targetCtx.getCopyHistory().getLastOperation() == CopyType.ADDED_BY_AUGMENTATION) {
+ if (targetCtx.history().getLastOperation() == CopyType.ADDED_BY_AUGMENTATION) {
final Optional<? extends StmtContext<?, ?, ?>> optPrevCopy = targetCtx.getPreviousCopyCtx();
if (optPrevCopy.isPresent()) {
final StmtContext<?, ?, ?> original = optPrevCopy.get();
return parent;
}
- private static boolean needToCopyByAugment(final StmtContext<?, ?, ?> stmtContext) {
- return !NOCOPY_DEF_SET.contains(stmtContext.publicDefinition());
- }
-
- private static boolean isReusedByAugment(final StmtContext<?, ?, ?> stmtContext) {
- return REUSED_DEF_SET.contains(stmtContext.publicDefinition());
- }
-
private static boolean isSupportedAugmentTarget(final StmtContext<?, ?, ?> substatementCtx) {
/*
* :TODO Substatement must be allowed augment target type e.g.