X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;ds=sidebyside;f=yang%2Fyang-parser-reactor%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fyangtools%2Fyang%2Fparser%2Fstmt%2Freactor%2FStatementContextBase.java;h=714d457fef4d10bb3205fc4dd768cd6b805b26af;hb=75276bc6d944ff002de8149108d60603349d49c6;hp=99635397caba87cd352d201526ef3ac908a48584;hpb=dca615ca52c236911179872709bc831493433048;p=yangtools.git diff --git a/yang/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/StatementContextBase.java b/yang/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/StatementContextBase.java index 99635397ca..714d457fef 100644 --- a/yang/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/StatementContextBase.java +++ b/yang/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/StatementContextBase.java @@ -7,9 +7,14 @@ */ package org.opendaylight.yangtools.yang.parser.stmt.reactor; +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkState; +import static java.util.Objects.requireNonNull; + +import com.google.common.annotations.Beta; import com.google.common.base.MoreObjects; import com.google.common.base.MoreObjects.ToStringHelper; -import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableCollection; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMultimap; @@ -22,12 +27,13 @@ import java.util.Collections; import java.util.EnumMap; import java.util.EventListener; import java.util.Iterator; +import java.util.List; import java.util.Map.Entry; +import java.util.Objects; import java.util.Optional; import java.util.Set; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; import org.opendaylight.yangtools.util.OptionalBoolean; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.common.QNameModule; @@ -39,6 +45,7 @@ import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition; import org.opendaylight.yangtools.yang.model.api.meta.StatementSource; import org.opendaylight.yangtools.yang.parser.spi.meta.CopyHistory; import org.opendaylight.yangtools.yang.parser.spi.meta.CopyType; +import org.opendaylight.yangtools.yang.parser.spi.meta.ImplicitParentAwareStatementSupport; import org.opendaylight.yangtools.yang.parser.spi.meta.ModelActionBuilder; import org.opendaylight.yangtools.yang.parser.spi.meta.ModelProcessingPhase; import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour; @@ -91,22 +98,23 @@ public abstract class StatementContextBase, E private static final Logger LOG = LoggerFactory.getLogger(StatementContextBase.class); - private final StatementDefinitionContext definition; - private final StatementSourceReference statementDeclSource; + private final @NonNull StatementDefinitionContext definition; + private final @NonNull StatementSourceReference statementDeclSource; private final StmtContext originalCtx; + private final StmtContext prevCopyCtx; private final CopyHistory copyHistory; private final String rawArgument; private Multimap phaseListeners = ImmutableMultimap.of(); private Multimap phaseMutation = ImmutableMultimap.of(); - private Collection> effective = ImmutableList.of(); - private Collection> effectOfStatement = ImmutableList.of(); + private List> effective = ImmutableList.of(); + private List> effectOfStatement = ImmutableList.of(); private StatementMap substatements = StatementMap.empty(); private boolean isSupportedToBuildEffective = true; - private ModelProcessingPhase completedPhase = null; - private D declaredInstance; - private E effectiveInstance; + private @Nullable ModelProcessingPhase completedPhase; + private @Nullable D declaredInstance; + private @Nullable E effectiveInstance; // BooleanFields value private byte supportedByFeatures; @@ -115,22 +123,42 @@ public abstract class StatementContextBase, E StatementContextBase(final StatementDefinitionContext def, final StatementSourceReference ref, final String rawArgument) { - this.definition = Preconditions.checkNotNull(def); - this.statementDeclSource = Preconditions.checkNotNull(ref); + this.definition = requireNonNull(def); + this.statementDeclSource = requireNonNull(ref); this.rawArgument = def.internArgument(rawArgument); this.copyHistory = CopyHistory.original(); this.originalCtx = null; + this.prevCopyCtx = null; + } + + StatementContextBase(final StatementDefinitionContext def, final StatementSourceReference ref, + final String rawArgument, final CopyType copyType) { + this.definition = requireNonNull(def); + this.statementDeclSource = requireNonNull(ref); + this.rawArgument = rawArgument; + this.copyHistory = CopyHistory.of(copyType, CopyHistory.original()); + this.originalCtx = null; + this.prevCopyCtx = null; } StatementContextBase(final StatementContextBase original, final CopyType copyType) { - this.definition = Preconditions.checkNotNull(original.definition, - "Statement context definition cannot be null copying from: %s", original.getStatementSourceReference()); - this.statementDeclSource = Preconditions.checkNotNull(original.statementDeclSource, - "Statement context statementDeclSource cannot be null copying from: %s", - original.getStatementSourceReference()); + this.definition = original.definition; + this.statementDeclSource = original.statementDeclSource; this.rawArgument = original.rawArgument; this.copyHistory = CopyHistory.of(copyType, original.getCopyHistory()); this.originalCtx = original.getOriginalCtx().orElse(original); + this.prevCopyCtx = original; + } + + StatementContextBase(final StatementContextBase original) { + this.definition = original.definition; + this.statementDeclSource = original.statementDeclSource; + this.rawArgument = original.rawArgument; + this.copyHistory = original.getCopyHistory(); + this.originalCtx = original.getOriginalCtx().orElse(original); + this.prevCopyCtx = original; + this.substatements = original.substatements; + this.effective = original.effective; } @Override @@ -187,9 +215,7 @@ public abstract class StatementContextBase, E // If the set of supported features has not been provided, all features are supported by default. final Set supportedFeatures = getFromNamespace(SupportedFeaturesNamespace.class, SupportedFeatures.SUPPORTED_FEATURES); - final boolean ret = supportedFeatures == null ? true - : StmtContextUtils.checkFeatureSupport(this, supportedFeatures); - + final boolean ret = supportedFeatures == null || StmtContextUtils.checkFeatureSupport(this, supportedFeatures); supportedByFeatures = OptionalBoolean.of(ret); return ret; } @@ -220,6 +246,11 @@ public abstract class StatementContextBase, E return Optional.ofNullable(originalCtx); } + @Override + public Optional> getPreviousCopyCtx() { + return Optional.ofNullable(prevCopyCtx); + } + @Override public ModelProcessingPhase getCompletedPhase() { return completedPhase; @@ -238,7 +269,6 @@ public abstract class StatementContextBase, E * * @return root context of statement */ - @Nonnull @Override public abstract RootStatementContext getRoot(); @@ -247,7 +277,6 @@ public abstract class StatementContextBase, E * * @return origin of statement */ - @Nonnull @Override public StatementSource getStatementSource() { return statementDeclSource.getStatementSource(); @@ -258,7 +287,6 @@ public abstract class StatementContextBase, E * * @return reference of statement source */ - @Nonnull @Override public StatementSourceReference getStatementSourceReference() { return statementDeclSource; @@ -269,13 +297,11 @@ public abstract class StatementContextBase, E return rawArgument; } - @Nonnull @Override public Collection> declaredSubstatements() { return substatements.values(); } - @Nonnull @Override public Collection> mutableDeclaredSubstatements() { return substatements.values(); @@ -286,7 +312,6 @@ public abstract class StatementContextBase, E return mutableEffectiveSubstatements(); } - @Nonnull @Override public Collection> mutableEffectiveSubstatements() { if (effective instanceof ImmutableCollection) { @@ -296,6 +321,15 @@ public abstract class StatementContextBase, E return Collections.unmodifiableCollection(effective); } + /** + * Remove a set of statements from effective statements. + * + * @param statements statements to be removed + * @deprecated This method was used by EffectiveStatementBase to restore proper order of effects of uses statements. + * It is no longer used in that capacity and slated for removal. + */ + // FIXME: 5.0.0: remove this method + @Deprecated(forRemoval = true) public void removeStatementsFromEffectiveSubstatements( final Collection> statements) { if (!effective.isEmpty()) { @@ -387,14 +421,14 @@ public abstract class StatementContextBase, E return; } - statements.forEach(Preconditions::checkNotNull); + statements.forEach(Objects::requireNonNull); beforeAddEffectiveStatement(statements.size()); effective.addAll(statements); } private void beforeAddEffectiveStatement(final int toAdd) { final ModelProcessingPhase inProgressPhase = getRoot().getSourceContext().getInProgressPhase(); - Preconditions.checkState(inProgressPhase == ModelProcessingPhase.FULL_DECLARATION + checkState(inProgressPhase == ModelProcessingPhase.FULL_DECLARATION || inProgressPhase == ModelProcessingPhase.EFFECTIVE_MODEL, "Effective statement cannot be added in declared phase at: %s", getStatementSourceReference()); @@ -410,15 +444,18 @@ public abstract class StatementContextBase, E * @param def definition context * @param ref source reference * @param argument statement argument + * @param new substatement argument type + * @param new substatement declared type + * @param new substatement effective type * @return A new substatement */ @SuppressWarnings("checkstyle:methodTypeParameterName") - public final , CE extends EffectiveStatement> - StatementContextBase createSubstatement(final int offset, - final StatementDefinitionContext def, final StatementSourceReference ref, + public final , Z extends EffectiveStatement> + StatementContextBase createSubstatement(final int offset, + final StatementDefinitionContext def, final StatementSourceReference ref, final String argument) { final ModelProcessingPhase inProgressPhase = getRoot().getSourceContext().getInProgressPhase(); - Preconditions.checkState(inProgressPhase != ModelProcessingPhase.EFFECTIVE_MODEL, + checkState(inProgressPhase != ModelProcessingPhase.EFFECTIVE_MODEL, "Declared statement cannot be added in effective phase at: %s", getStatementSourceReference()); final Optional> implicitParent = definition.getImplicitParentFor(def.getPublicView()); @@ -427,7 +464,7 @@ public abstract class StatementContextBase, E ref, argument); } - final StatementContextBase ret = new SubstatementContext<>(this, def, ref, argument); + final StatementContextBase ret = new SubstatementContext<>(this, def, ref, argument); substatements = substatements.put(offset, ret); def.onStatementAdded(ret); return ret; @@ -463,7 +500,7 @@ public abstract class StatementContextBase, E } final void walkChildren(final ModelProcessingPhase phase) { - Preconditions.checkState(fullyDefined); + checkState(fullyDefined); substatements.values().forEach(stmt -> { stmt.walkChildren(phase); stmt.endDeclared(phase); @@ -472,7 +509,7 @@ public abstract class StatementContextBase, E @Override public D buildDeclared() { - Preconditions.checkArgument(completedPhase == ModelProcessingPhase.FULL_DECLARATION + checkArgument(completedPhase == ModelProcessingPhase.FULL_DECLARATION || completedPhase == ModelProcessingPhase.EFFECTIVE_MODEL); if (declaredInstance == null) { declaredInstance = definition().getFactory().createDeclared(this); @@ -495,7 +532,7 @@ public abstract class StatementContextBase, E * to be executed (completed) * @return if phase was successfully completed * @throws SourceException - * when an error occured in source parsing + * when an error occurred in source parsing */ boolean tryToCompletePhase(final ModelProcessingPhase phase) { @@ -580,7 +617,7 @@ public abstract class StatementContextBase, E * * @return statement definition */ - protected final StatementDefinitionContext definition() { + protected final @NonNull StatementDefinitionContext definition() { return definition; } @@ -604,7 +641,7 @@ public abstract class StatementContextBase, E return; } - getBehaviour(type).addListener(new KeyedValueAddedListener(this, key) { + getBehaviour(type).addListener(new KeyedValueAddedListener<>(this, key) { @Override void onValueAdded(final Object value) { listener.namespaceItemAdded(StatementContextBase.this, type, key, value); @@ -641,8 +678,8 @@ public abstract class StatementContextBase, E final > void selectMatch(final Class type, final NamespaceKeyCriterion criterion, final OnNamespaceItemAdded listener) { final Optional> optMatch = getFromNamespace(type, criterion); - Preconditions.checkState(optMatch.isPresent(), - "Failed to find a match for criterion %s in namespace %s node %s", criterion, type, this); + checkState(optMatch.isPresent(), "Failed to find a match for criterion %s in namespace %s node %s", criterion, + type, this); final Entry match = optMatch.get(); listener.namespaceItemAdded(StatementContextBase.this, type, match.getKey(), match.getValue()); } @@ -660,8 +697,8 @@ public abstract class StatementContextBase, E private > NamespaceBehaviourWithListeners getBehaviour( final Class type) { final NamespaceBehaviour behaviour = getBehaviourRegistry().getNamespaceBehaviour(type); - Preconditions.checkArgument(behaviour instanceof NamespaceBehaviourWithListeners, - "Namespace %s does not support listeners", type); + checkArgument(behaviour instanceof NamespaceBehaviourWithListeners, "Namespace %s does not support listeners", + type); return (NamespaceBehaviourWithListeners) behaviour; } @@ -669,7 +706,6 @@ public abstract class StatementContextBase, E /** * See {@link StatementSupport#getPublicView()}. */ - @Nonnull @Override public StatementDefinition getPublicDefinition() { return definition().getPublicView(); @@ -693,10 +729,8 @@ public abstract class StatementContextBase, E * @throws NullPointerException if any of the arguments is null */ void addPhaseCompletedListener(final ModelProcessingPhase phase, final OnPhaseFinished listener) { - Preconditions.checkNotNull(phase, "Statement context processing phase cannot be null at: %s", - getStatementSourceReference()); - Preconditions.checkNotNull(listener, "Statement context phase listener cannot be null at: %s", - getStatementSourceReference()); + checkNotNull(phase, "Statement context processing phase cannot be null at: %s", getStatementSourceReference()); + checkNotNull(listener, "Statement context phase listener cannot be null at: %s", getStatementSourceReference()); ModelProcessingPhase finishedPhase = completedPhase; while (finishedPhase != null) { @@ -722,8 +756,8 @@ public abstract class StatementContextBase, E void addMutation(final ModelProcessingPhase phase, final ContextMutation mutation) { ModelProcessingPhase finishedPhase = completedPhase; while (finishedPhase != null) { - Preconditions.checkState(!phase.equals(finishedPhase), - "Mutation registered after phase was completed at: %s", getStatementSourceReference()); + checkState(!phase.equals(finishedPhase), "Mutation registered after phase was completed at: %s", + getStatementSourceReference()); finishedPhase = finishedPhase.getPreviousPhase(); } @@ -742,20 +776,48 @@ public abstract class StatementContextBase, E @Override public , Z extends EffectiveStatement> Mutable childCopyOf( final StmtContext stmt, final CopyType type, final QNameModule targetModule) { - Preconditions.checkState(stmt.getCompletedPhase() == ModelProcessingPhase.EFFECTIVE_MODEL, + checkState(stmt.getCompletedPhase() == ModelProcessingPhase.EFFECTIVE_MODEL, "Attempted to copy statement %s which has completed phase %s", stmt, stmt.getCompletedPhase()); - Preconditions.checkArgument(stmt instanceof SubstatementContext, "Unsupported statement %s", stmt); + checkArgument(stmt instanceof SubstatementContext, "Unsupported statement %s", stmt); final SubstatementContext original = (SubstatementContext)stmt; - final SubstatementContext copy = new SubstatementContext<>(original, this, type, targetModule); + final Optional> implicitParent = definition.getImplicitParentFor( + original.getPublicDefinition()); - original.definition().onStatementAdded(copy); - original.copyTo(copy, type, targetModule); + final SubstatementContext result; + final SubstatementContext copy; - return copy; - } + if (implicitParent.isPresent()) { + final StatementDefinitionContext def = new StatementDefinitionContext<>(implicitParent.get()); + result = new SubstatementContext(this, def, original.getSourceReference(), + original.rawStatementArgument(), original.getStatementArgument(), type); + + final CopyType childCopyType; + switch (type) { + case ADDED_BY_AUGMENTATION: + childCopyType = CopyType.ORIGINAL; + break; + case ADDED_BY_USES_AUGMENTATION: + childCopyType = CopyType.ADDED_BY_USES; + break; + case ADDED_BY_USES: + case ORIGINAL: + default: + childCopyType = type; + } + + copy = new SubstatementContext<>(original, result, childCopyType, targetModule); + result.addEffectiveSubstatement(copy); + original.definition().onStatementAdded(copy); + } else { + result = copy = new SubstatementContext<>(original, this, type, targetModule); + original.definition().onStatementAdded(copy); + } + original.copyTo(copy, type, targetModule); + return result; + } @Override public @NonNull StatementDefinition getDefinition() { @@ -772,6 +834,30 @@ public abstract class StatementContextBase, E return fullyDefined; } + @Beta + public final boolean hasImplicitParentSupport() { + return definition.getFactory() instanceof ImplicitParentAwareStatementSupport; + } + + @Beta + public final StatementContextBase wrapWithImplicit(final StatementContextBase original) { + final Optional> optImplicit = definition.getImplicitParentFor( + original.getPublicDefinition()); + if (optImplicit.isEmpty()) { + return original; + } + + final StatementDefinitionContext def = new StatementDefinitionContext<>(optImplicit.get()); + final CopyType type = original.getCopyHistory().getLastOperation(); + final SubstatementContext result = new SubstatementContext(original.getParentContext(), def, + original.getStatementSourceReference(), original.rawStatementArgument(), original.getStatementArgument(), + type); + + result.addEffectiveSubstatement(new SubstatementContext<>(original, result)); + result.setCompletedPhase(original.getCompletedPhase()); + return result; + } + final void copyTo(final StatementContextBase target, final CopyType typeOfCopy, @Nullable final QNameModule targetModule) { final Collection> buffer = new ArrayList<>(substatements.size() + effective.size()); @@ -793,7 +879,7 @@ public abstract class StatementContextBase, E final CopyType typeOfCopy, final QNameModule newQNameModule, final Collection> buffer) { if (needToCopyByUses(stmtContext)) { final Mutable copy = target.childCopyOf(stmtContext, typeOfCopy, newQNameModule); - LOG.debug("Copying substatement {} for {} as", stmtContext, this, copy); + LOG.debug("Copying substatement {} for {} as {}", stmtContext, this, copy); buffer.add(copy); } else if (isReusedByUses(stmtContext)) { LOG.debug("Reusing substatement {} for {}", stmtContext, this); @@ -804,11 +890,11 @@ public abstract class StatementContextBase, E } // FIXME: revise this, as it seems to be wrong - private static final Set NOCOPY_FROM_GROUPING_SET = ImmutableSet.of( + private static final ImmutableSet NOCOPY_FROM_GROUPING_SET = ImmutableSet.of( YangStmtMapping.DESCRIPTION, YangStmtMapping.REFERENCE, YangStmtMapping.STATUS); - private static final Set REUSED_DEF_SET = ImmutableSet.of( + private static final ImmutableSet REUSED_DEF_SET = ImmutableSet.of( YangStmtMapping.TYPE, YangStmtMapping.TYPEDEF, YangStmtMapping.USES); @@ -820,7 +906,7 @@ public abstract class StatementContextBase, E return false; } if (NOCOPY_FROM_GROUPING_SET.contains(def)) { - return !YangStmtMapping.GROUPING.equals(stmtContext.getParentContext().getPublicDefinition()); + return !YangStmtMapping.GROUPING.equals(stmtContext.coerceParentContext().getPublicDefinition()); } LOG.debug("Will copy {} statement {}", def, stmtContext);