private static void performRefine(final Mutable<?, ?, ?> subStmtCtx, final StmtContext<?, ?, ?> usesParentCtx) { final Object refineArgument = subStmtCtx.getStatementArgument(); InferenceException.throwIf(!(refineArgument instanceof SchemaNodeIdentifier), subStmtCtx.getStatementSourceReference(), "Invalid refine argument %s. It must be instance of SchemaNodeIdentifier.", refineArgument); final Optional<StmtContext<?, ?, ?>> optRefineTargetCtx = ChildSchemaNodeNamespace.findNode( usesParentCtx, (SchemaNodeIdentifier) refineArgument); InferenceException.throwIf(!optRefineTargetCtx.isPresent(), subStmtCtx.getStatementSourceReference(), "Refine target node %s not found.", refineArgument); final StmtContext<?, ?, ?> refineTargetNodeCtx = optRefineTargetCtx.get(); if (StmtContextUtils.isUnknownStatement(refineTargetNodeCtx)) { LOG.trace("Refine node '{}' in uses '{}' has target node unknown statement '{}'. " + "Refine has been skipped. At line: {}", subStmtCtx.getStatementArgument(), subStmtCtx.coerceParentContext().getStatementArgument(), refineTargetNodeCtx.getStatementArgument(), subStmtCtx.getStatementSourceReference()); subStmtCtx.addAsEffectOfStatement(refineTargetNodeCtx); return; } Verify.verify(refineTargetNodeCtx instanceof StatementContextBase); addOrReplaceNodes(subStmtCtx, (StatementContextBase<?, ?, ?>) refineTargetNodeCtx); subStmtCtx.addAsEffectOfStatement(refineTargetNodeCtx); }
private static void replaceStatement(final Mutable<?, ?, ?> stmtCtxToBeReplaced, final StatementContextBase<?, ?, ?> targetCtx) { final StatementDefinition stmtToBeReplaced = stmtCtxToBeReplaced.getPublicDefinition(); LOG.error("Deviation cannot replace substatement {} in target leaf-list {} because a leaf-list can " + "have multiple default statements. At line: {}", stmtToBeReplaced.getStatementName(), targetCtx.getStatementArgument(), stmtCtxToBeReplaced.getStatementSourceReference()); return; if (stmtToBeReplaced.equals(targetCtxSubstatement.getPublicDefinition())) { targetCtxSubstatement.setIsSupportedToBuildEffective(false); copyStatement(stmtCtxToBeReplaced, targetCtx); return; throw new InferenceException(stmtCtxToBeReplaced.getStatementSourceReference(), "Deviation cannot replace " + "substatement %s in target node %s because it does not exist in target node.", stmtToBeReplaced.getStatementName(), targetCtx.getStatementArgument());
@Override public void apply(final InferenceContext ctx) { List<StmtContext<?, ?, ?>> derivedIdentities = baseStmtCtx.getFromNamespace( DerivedIdentitiesNamespace.class, baseIdentityQName); if (derivedIdentities == null) { derivedIdentities = new ArrayList<>(1); baseStmtCtx.addToNs(DerivedIdentitiesNamespace.class, baseIdentityQName, derivedIdentities); } derivedIdentities.add(baseParentCtx); }
@Override public final void onFullDefinitionDeclared(final Mutable<SchemaNodeIdentifier, AugmentStatement, EffectiveStatement<SchemaNodeIdentifier, AugmentStatement>> augmentNode) { if (!augmentNode.isSupportedByFeatures()) { return; final ModelActionBuilder augmentAction = augmentNode.newInferenceAction( ModelProcessingPhase.EFFECTIVE_MODEL); final Prerequisite<StmtContext<SchemaNodeIdentifier, AugmentStatement, final Prerequisite<Mutable<?, ?, EffectiveStatement<?, ?>>> target = augmentAction.mutatesEffectiveCtxPath(getSearchRoot(augmentNode), ChildSchemaNodeNamespace.class, augmentNode.coerceStatementArgument().getPathFromRoot());
@Override public final void onFullDefinitionDeclared(final Mutable<DeviateKind, DeviateStatement, EffectiveStatement<DeviateKind, DeviateStatement>> deviateStmtCtx) { final DeviateKind deviateKind = deviateStmtCtx.getStatementArgument(); getSubstatementValidatorForDeviate(deviateKind).validate(deviateStmtCtx); (SchemaNodeIdentifier) deviateStmtCtx.coerceParentContext().getStatementArgument(); final ModelActionBuilder deviateAction = deviateStmtCtx.newInferenceAction( ModelProcessingPhase.EFFECTIVE_MODEL); deviateAction.mutatesEffectiveCtxPath(deviateStmtCtx.getRoot(), ChildSchemaNodeNamespace.class, deviationTarget.getPathFromRoot());
final Mutable<?, ?, ?> root = targetCtx.getRoot(); do { Verify.verify(targetCtx.getStatementArgument() instanceof QName, "Argument of augment target statement must be QName."); final QName targetStmtQName = (QName) targetCtx.getStatementArgument(); return false; } while ((targetCtx = targetCtx.getParentContext()) != root);
@Override public void onFullDefinitionDeclared( final Mutable<QName, UsesStatement, EffectiveStatement<QName, UsesStatement>> usesNode) { if (!usesNode.isSupportedByFeatures()) { return; final ModelActionBuilder usesAction = usesNode.newInferenceAction(ModelProcessingPhase.EFFECTIVE_MODEL); final QName groupingName = usesNode.getStatementArgument(); usesNode.getParentContext());
final Optional<URI> moduleNs = Optional.ofNullable(firstAttributeOf(stmt.declaredSubstatements(), NamespaceStatement.class)); SourceException.throwIf(!moduleNs.isPresent(), stmt.getStatementSourceReference(), "Namespace of the module [%s] is missing", stmt.getStatementArgument()); final Optional<Revision> revisionDate = StmtContextUtils.getLatestRevision(stmt.declaredSubstatements()); final QNameModule qNameModule = QNameModule.create(moduleNs.get(), revisionDate.orElse(null)).intern(); final StmtContext<?, ModuleStatement, EffectiveStatement<String, ModuleStatement>> possibleDuplicateModule = stmt.getFromNamespace(NamespaceToModule.class, qNameModule); if (possibleDuplicateModule != null && possibleDuplicateModule != stmt) { throw new SourceException(stmt.getStatementSourceReference(), "Module namespace collision: %s. At %s", qNameModule.getNamespace(), possibleDuplicateModule.getStatementSourceReference()); final SourceIdentifier moduleIdentifier = RevisionSourceIdentifier.create(stmt.getStatementArgument(), revisionDate); stmt.addContext(ModuleNamespace.class, moduleIdentifier, stmt); stmt.addContext(ModuleNamespaceForBelongsTo.class, moduleIdentifier.getName(), stmt); stmt.addContext(NamespaceToModule.class, qNameModule, stmt); final String modulePrefix = firstAttributeOf(stmt.declaredSubstatements(), PrefixStatement.class); SourceException.throwIfNull(modulePrefix, stmt.getStatementSourceReference(), "Prefix of the module [%s] is missing", stmt.getStatementArgument()); stmt.addToNs(PrefixToModule.class, modulePrefix, qNameModule); stmt.addToNs(ModuleNameToModuleQName.class, stmt.getStatementArgument(), qNameModule); stmt.addToNs(ModuleCtxToModuleQName.class, stmt, qNameModule); stmt.addToNs(ModuleCtxToSourceIdentifier.class, stmt, moduleIdentifier); stmt.addToNs(ModuleQNameToModuleName.class, qNameModule, stmt.getStatementArgument());
@Override public final void onFullDefinitionDeclared( final Mutable<String, TypeStatement, EffectiveStatement<String, TypeStatement>> stmt) { super.onFullDefinitionDeclared(stmt); // if it is yang built-in type, no prerequisite is needed, so simply return if (BUILT_IN_TYPES.containsKey(stmt.getStatementArgument())) { return; } final QName typeQName = StmtContextUtils.parseNodeIdentifier(stmt, stmt.getStatementArgument()); final ModelActionBuilder typeAction = stmt.newInferenceAction(ModelProcessingPhase.EFFECTIVE_MODEL); final Prerequisite<StmtContext<?, ?, ?>> typePrereq = typeAction.requiresCtx(stmt, TypeNamespace.class, typeQName, ModelProcessingPhase.EFFECTIVE_MODEL); typeAction.mutatesEffectiveCtx(stmt.getParentContext()); /* * If the type does not exist, throw new InferenceException. * Otherwise perform no operation. */ typeAction.apply(new InferenceAction() { @Override public void apply(final InferenceContext ctx) { // Intentional NOOP } @Override public void prerequisiteFailed(final Collection<? extends Prerequisite<?>> failed) { InferenceException.throwIf(failed.contains(typePrereq), stmt.getStatementSourceReference(), "Type [%s] was not found.", typeQName); } }); }
@Override public void onStatementDefinitionDeclared( final Mutable<QName, BaseStatement, EffectiveStatement<QName, BaseStatement>> baseStmtCtx) { final Mutable<?, ?, ?> baseParentCtx = baseStmtCtx.getParentContext(); if (StmtContextUtils.producesDeclared(baseParentCtx, IdentityStatement.class)) { final QName baseIdentityQName = baseStmtCtx.coerceStatementArgument(); final ModelActionBuilder baseIdentityAction = baseStmtCtx.newInferenceAction( ModelProcessingPhase.STATEMENT_DEFINITION); final Prerequisite<StmtContext<?, ?, ?>> requiresPrereq = baseIdentityAction.requiresCtx(baseStmtCtx,
/** * Copy statements from a grouping to a target node. * * @param sourceGrpStmtCtx * source grouping statement context * @param targetCtx * target context * @param usesNode * uses node * @throws SourceException * instance of SourceException */ static void copyFromSourceToTarget(final Mutable<?, ?, ?> sourceGrpStmtCtx, final StatementContextBase<?, ?, ?> targetCtx, final Mutable<QName, UsesStatement, EffectiveStatement<QName, UsesStatement>> usesNode) { final Collection<? extends Mutable<?, ?, ?>> declared = sourceGrpStmtCtx.mutableDeclaredSubstatements(); final Collection<? extends Mutable<?, ?, ?>> effective = sourceGrpStmtCtx.mutableEffectiveSubstatements(); final Collection<Mutable<?, ?, ?>> buffer = new ArrayList<>(declared.size() + effective.size()); final QNameModule newQNameModule = getNewQNameModule(targetCtx, sourceGrpStmtCtx); for (final Mutable<?, ?, ?> original : declared) { if (original.isSupportedByFeatures()) { copyStatement(original, targetCtx, newQNameModule, buffer); } } for (final Mutable<?, ?, ?> original : effective) { copyStatement(original, targetCtx, newQNameModule, buffer); } targetCtx.addEffectiveSubstatements(buffer); usesNode.addAsEffectOfStatement(buffer); }
/** * Removes a statement context from the effective substatements based on its statement definition (i.e statement * keyword) and raw (in String form) statement argument. The statement context is removed only if both statement * definition and statement argument match with one of the effective substatements' statement definition * and argument. * * <p> * If the statementArg parameter is null, the statement context is removed based only on its statement definition. * * @param statementDef statement definition of the statement context to remove * @param statementArg statement argument of the statement context to remove */ public void removeStatementFromEffectiveSubstatements(final StatementDefinition statementDef, final String statementArg) { if (statementArg == null) { removeStatementFromEffectiveSubstatements(statementDef); } if (effective.isEmpty()) { return; } final Iterator<Mutable<?, ?, ?>> iterator = effective.iterator(); while (iterator.hasNext()) { final Mutable<?, ?, ?> next = iterator.next(); if (statementDef.equals(next.getPublicDefinition()) && statementArg.equals(next.rawStatementArgument())) { iterator.remove(); } } shrinkEffective(); }
static void copyFromSourceToTarget(final StatementContextBase<?, ?, ?> sourceCtx, final StatementContextBase<?, ?, ?> targetCtx) { final CopyType typeOfCopy = UsesStatement.class.equals(sourceCtx.coerceParentContext().getPublicDefinition() .getDeclaredRepresentationClass()) ? CopyType.ADDED_BY_USES_AUGMENTATION : CopyType.ADDED_BY_AUGMENTATION; /* * Since Yang 1.1, if an augmentation is made conditional with a * "when" statement, it is allowed to add mandatory nodes. */ final boolean skipCheckOfMandatoryNodes = YangVersion.VERSION_1_1.equals(sourceCtx.getRootVersion()) && isConditionalAugmentStmt(sourceCtx); final Collection<? extends Mutable<?, ?, ?>> declared = sourceCtx.mutableDeclaredSubstatements(); final Collection<? extends Mutable<?, ?, ?>> effective = sourceCtx.mutableEffectiveSubstatements(); final Collection<Mutable<?, ?, ?>> buffer = new ArrayList<>(declared.size() + effective.size()); for (final Mutable<?, ?, ?> originalStmtCtx : declared) { if (originalStmtCtx.isSupportedByFeatures()) { copyStatement(originalStmtCtx, targetCtx, typeOfCopy, buffer, skipCheckOfMandatoryNodes); } } for (final Mutable<?, ?, ?> originalStmtCtx : effective) { copyStatement(originalStmtCtx, targetCtx, typeOfCopy, buffer, skipCheckOfMandatoryNodes); } targetCtx.addEffectiveSubstatements(buffer); }
@Override public void apply(final InferenceContext ctx) { final StatementContextBase<?, ?, ?> augmentTargetCtx = (StatementContextBase<?, ?, ?>) target.resolve(ctx); if (!isSupportedAugmentTarget(augmentTargetCtx) || StmtContextUtils.isInExtensionBody(augmentTargetCtx)) { augmentNode.setIsSupportedToBuildEffective(false); return; } /** * Marks case short hand in augment */ if (augmentTargetCtx.getPublicDefinition() == YangStmtMapping.CHOICE) { augmentNode.addToNs(AugmentToChoiceNamespace.class, augmentNode, Boolean.TRUE); } // 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. final StatementContextBase<?, ?, ?> augmentSourceCtx = (StatementContextBase<?, ?, ?>) augmentNode; try { copyFromSourceToTarget(augmentSourceCtx, augmentTargetCtx); augmentTargetCtx.addEffectiveSubstatement(augmentSourceCtx); updateAugmentOrder(augmentSourceCtx); } catch (final SourceException e) { LOG.warn("Failed to add augmentation {} defined at {}", augmentTargetCtx.getStatementSourceReference(), augmentSourceCtx.getStatementSourceReference(), e); } }
@Override public final void onLinkageDeclared( final Mutable<String, SubmoduleStatement, EffectiveStatement<String, SubmoduleStatement>> stmt) { final SourceIdentifier submoduleIdentifier = RevisionSourceIdentifier.create(stmt.coerceStatementArgument(), StmtContextUtils.getLatestRevision(stmt.declaredSubstatements())); final StmtContext<?, SubmoduleStatement, EffectiveStatement<String, SubmoduleStatement>> possibleDuplicateSubmodule = stmt.getFromNamespace(SubmoduleNamespace.class, submoduleIdentifier); if (possibleDuplicateSubmodule != null && possibleDuplicateSubmodule != stmt) { throw new SourceException(stmt.getStatementSourceReference(), "Submodule name collision: %s. At %s", stmt.getStatementArgument(), possibleDuplicateSubmodule.getStatementSourceReference()); } stmt.addContext(SubmoduleNamespace.class, submoduleIdentifier, stmt); final String belongsToModuleName = firstAttributeOf(stmt.declaredSubstatements(), BelongsToStatement.class); final StmtContext<?, ?, ?> prefixSubStmtCtx = findFirstDeclaredSubstatement(stmt, 0, BelongsToStatement.class, PrefixStatement.class); SourceException.throwIfNull(prefixSubStmtCtx, stmt.getStatementSourceReference(), "Prefix of belongsTo statement is missing in submodule [%s]", stmt.getStatementArgument()); final String prefix = (String) prefixSubStmtCtx.getStatementArgument(); stmt.addToNs(BelongsToPrefixToModuleName.class, prefix, belongsToModuleName); } }
private static void deleteStatement(final StmtContext<?, ?, ?> stmtCtxToBeDeleted, final StatementContextBase<?, ?, ?> targetCtx) { final StatementDefinition stmtToBeDeleted = stmtCtxToBeDeleted.getPublicDefinition(); final String stmtArgument = stmtCtxToBeDeleted.rawStatementArgument(); for (final Mutable<?, ?, ?> targetCtxSubstatement : targetCtx.mutableEffectiveSubstatements()) { if (statementsAreEqual(stmtToBeDeleted, stmtArgument, targetCtxSubstatement.getPublicDefinition(), targetCtxSubstatement.rawStatementArgument())) { targetCtx.removeStatementFromEffectiveSubstatements(stmtToBeDeleted, stmtArgument); return; } } for (final Mutable<?, ?, ?> targetCtxSubstatement : targetCtx.mutableDeclaredSubstatements()) { if (statementsAreEqual(stmtToBeDeleted, stmtArgument, targetCtxSubstatement.getPublicDefinition(), targetCtxSubstatement.rawStatementArgument())) { targetCtxSubstatement.setIsSupportedToBuildEffective(false); return; } } LOG.error("Deviation cannot delete substatement {} with argument '{}' in target node {} because it does " + "not exist in the target node. At line: {}", stmtToBeDeleted.getStatementName(), stmtArgument, targetCtx.getStatementArgument(), stmtCtxToBeDeleted.getStatementSourceReference()); }
@Override public AnyxmlEffectiveStatement createEffective( final StmtContext<QName, AnyxmlStatement, AnyxmlEffectiveStatement> ctx) { final AnyxmlEffectiveStatement delegateStatement = delegate().createEffective(ctx); final Map<StatementDefinition, Mutable<SchemaNodeIdentifier, AnyxmlSchemaLocationStatement, EffectiveStatement<SchemaNodeIdentifier, AnyxmlSchemaLocationStatement>>> schemaLocations = ctx.getAllFromCurrentStmtCtxNamespace(AnyxmlSchemaLocationNamespace.class); if (schemaLocations != null && !schemaLocations.isEmpty()) { final SchemaNodeIdentifier anyXmlSchemaNodeIdentifier = schemaLocations.values().iterator().next() .getStatementArgument(); final Optional<ContainerSchemaNode> anyXmlSchema = getAnyXmlSchema(ctx, anyXmlSchemaNodeIdentifier); if (anyXmlSchema.isPresent()) { return new YangModeledAnyxmlEffectiveStatementImpl(delegateStatement, anyXmlSchema.get()); } } return delegateStatement; }
@Override public void prerequisiteFailed(final Collection<? extends Prerequisite<?>> failed) { /* * Do not fail, if it is an uses-augment to an unknown node. */ if (YangStmtMapping.USES == augmentNode.coerceParentContext().getPublicDefinition()) { final SchemaNodeIdentifier augmentArg = augmentNode.coerceStatementArgument(); final Optional<StmtContext<?, ?, ?>> targetNode = ChildSchemaNodeNamespace.findNode( getSearchRoot(augmentNode), augmentArg); if (targetNode.isPresent() && StmtContextUtils.isUnknownStatement(targetNode.get())) { augmentNode.setIsSupportedToBuildEffective(false); LOG.warn("Uses-augment to unknown node {}. Augmentation has not been performed. At line: {}", augmentArg, augmentNode.getStatementSourceReference()); return; } } throw new InferenceException(augmentNode.getStatementSourceReference(), "Augment target '%s' not found", augmentNode.getStatementArgument()); } });
private static void addStatement(final Mutable<?, ?, ?> stmtCtxToBeAdded, final StatementContextBase<?, ?, ?> targetCtx) { if (!StmtContextUtils.isUnknownStatement(stmtCtxToBeAdded)) { final StatementDefinition stmtToBeAdded = stmtCtxToBeAdded.getPublicDefinition(); if (SINGLETON_STATEMENTS.contains(stmtToBeAdded) || YangStmtMapping.DEFAULT.equals(stmtToBeAdded) && YangStmtMapping.LEAF.equals(targetCtx.getPublicDefinition())) { for (final StmtContext<?, ?, ?> targetCtxSubstatement : targetCtx.allSubstatements()) { InferenceException.throwIf(stmtToBeAdded.equals(targetCtxSubstatement.getPublicDefinition()), stmtCtxToBeAdded.getStatementSourceReference(), "Deviation cannot add substatement %s to target node %s because it is already defined " + "in target and can appear only once.", stmtToBeAdded.getStatementName(), targetCtx.getStatementArgument()); } } } copyStatement(stmtCtxToBeAdded, targetCtx); }
@Override public AnyxmlEffectiveStatement createEffective( final StmtContext<QName, AnyxmlStatement, AnyxmlEffectiveStatement> ctx) { final AnyxmlEffectiveStatement delegateStatement = delegate().createEffective(ctx); final Map<StatementDefinition, Mutable<SchemaNodeIdentifier, AnyxmlSchemaLocationStatement, EffectiveStatement<SchemaNodeIdentifier, AnyxmlSchemaLocationStatement>>> schemaLocations = ctx.getAllFromCurrentStmtCtxNamespace(AnyxmlSchemaLocationNamespace.class); if (schemaLocations != null && !schemaLocations.isEmpty()) { final SchemaNodeIdentifier anyXmlSchemaNodeIdentifier = schemaLocations.values().iterator().next() .getStatementArgument(); final Optional<ContainerSchemaNode> anyXmlSchema = getAnyXmlSchema(ctx, anyXmlSchemaNodeIdentifier); if (anyXmlSchema.isPresent()) { return new YangModeledAnyxmlEffectiveStatementImpl(delegateStatement, anyXmlSchema.get()); } } return delegateStatement; }