X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=parser%2Fyang-parser-reactor%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fyangtools%2Fyang%2Fparser%2Fstmt%2Freactor%2FAbstractResumedStatement.java;h=1358f284ffe477610b07b80791922d3aa02e7200;hb=0f34ef9c1d749b903a476b84c3c54e5e98225669;hp=926fc6e6d92c884eda0232b1c20ce15f0716bcf2;hpb=f49cc93a33762dd4734a61bfc94961a8b301f850;p=yangtools.git diff --git a/parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/AbstractResumedStatement.java b/parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/AbstractResumedStatement.java index 926fc6e6d9..1358f284ff 100644 --- a/parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/AbstractResumedStatement.java +++ b/parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/AbstractResumedStatement.java @@ -10,28 +10,20 @@ package org.opendaylight.yangtools.yang.parser.stmt.reactor; import static com.google.common.base.Preconditions.checkState; import static com.google.common.base.Verify.verify; import static com.google.common.base.Verify.verifyNotNull; -import static java.util.Objects.requireNonNull; -import com.google.common.collect.ImmutableList; import java.util.Collection; -import java.util.List; -import java.util.Optional; import java.util.stream.Stream; import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.Nullable; 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.meta.StatementOrigin; -import org.opendaylight.yangtools.yang.parser.spi.meta.CopyType; import org.opendaylight.yangtools.yang.parser.spi.meta.ModelProcessingPhase; +import org.opendaylight.yangtools.yang.parser.spi.meta.StatementFactory; import org.opendaylight.yangtools.yang.parser.spi.meta.StatementSupport; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; -import org.opendaylight.yangtools.yang.parser.spi.source.ImplicitSubstatement; import org.opendaylight.yangtools.yang.parser.spi.source.StatementSourceReference; import org.opendaylight.yangtools.yang.parser.spi.source.StatementWriter.ResumedStatement; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** * Intermediate subclass of StatementContextBase facing the parser stream via implementation of ResumedStatement. This @@ -42,20 +34,15 @@ import org.slf4j.LoggerFactory; * @param Effective Statement representation */ abstract class AbstractResumedStatement, E extends EffectiveStatement> - extends StatementContextBase implements ResumedStatement { - private static final Logger LOG = LoggerFactory.getLogger(AbstractResumedStatement.class); - - private final @NonNull StatementSourceReference statementDeclSource; + extends OriginalStmtCtx implements ResumedStatement { private final String rawArgument; - private List> effective = ImmutableList.of(); private StatementMap substatements = StatementMap.empty(); private @Nullable D declaredInstance; // Copy constructor AbstractResumedStatement(final AbstractResumedStatement original) { super(original); - this.statementDeclSource = original.statementDeclSource; this.rawArgument = original.rawArgument; this.substatements = original.substatements; this.declaredInstance = original.declaredInstance; @@ -63,33 +50,10 @@ abstract class AbstractResumedStatement, E ext AbstractResumedStatement(final StatementDefinitionContext def, final StatementSourceReference ref, final String rawArgument) { - super(def); - this.statementDeclSource = requireNonNull(ref); + super(def, ref); this.rawArgument = def.support().internArgument(rawArgument); } - AbstractResumedStatement(final StatementDefinitionContext def, final StatementSourceReference ref, - final String rawArgument, final CopyType copyType) { - super(def, copyType); - this.statementDeclSource = requireNonNull(ref); - this.rawArgument = rawArgument; - } - - @Override - public final Optional> getOriginalCtx() { - return Optional.empty(); - } - - @Override - public final Optional> getPreviousCopyCtx() { - return Optional.empty(); - } - - @Override - public final StatementSourceReference sourceReference() { - return statementDeclSource; - } - @Override public final String rawArgument() { return rawArgument; @@ -97,33 +61,7 @@ abstract class AbstractResumedStatement, E ext @Override public Collection> mutableDeclaredSubstatements() { - return substatements; - } - - @Override - public final Collection> mutableEffectiveSubstatements() { - return mutableEffectiveSubstatements(effective); - } - - @Override - public final void removeStatementFromEffectiveSubstatements(final StatementDefinition statementDef) { - effective = removeStatementFromEffectiveSubstatements(effective, statementDef); - } - - @Override - public final void removeStatementFromEffectiveSubstatements(final StatementDefinition statementDef, - final String statementArg) { - effective = removeStatementFromEffectiveSubstatements(effective, statementDef, statementArg); - } - - @Override - public final void addEffectiveSubstatement(final Mutable substatement) { - effective = addEffectiveSubstatement(effective, substatement); - } - - @Override - final void addEffectiveSubstatementsImpl(final Collection> statements) { - effective = addEffectiveSubstatementsImpl(effective, statements); + return verifyNotNull(substatements); } @Override @@ -136,7 +74,19 @@ abstract class AbstractResumedStatement, E ext final ModelProcessingPhase phase = getCompletedPhase(); checkState(phase == ModelProcessingPhase.FULL_DECLARATION || phase == ModelProcessingPhase.EFFECTIVE_MODEL, "Cannot build declared instance after phase %s", phase); - return declaredInstance = definition().getFactory().createDeclared(this); + return declaredInstance = definition().getFactory().createDeclared(this, substatementsAsDeclared()); + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + private @NonNull Stream> substatementsAsDeclared() { + final Stream> stream; + if (getImplicitDeclaredFlag()) { + stream = substatements.stream().map(AbstractResumedStatement::unmaskUndeclared); + } else { + stream = (Stream) substatements.stream(); + } + + return stream.map(AbstractResumedStatement::declared); } @Override @@ -146,7 +96,7 @@ abstract class AbstractResumedStatement, E ext @Override public final StatementSourceReference getSourceReference() { - return statementDeclSource; + return sourceReference(); } @Override @@ -154,6 +104,33 @@ abstract class AbstractResumedStatement, E ext return fullyDefined(); } + @Override + final E createEffective(final StatementFactory factory) { + return createEffective(factory, this, streamDeclared(), streamEffective()); + } + + // Creates EffectiveStatement through full materialization and assumes declared statement presence + private @NonNull E createEffective(final StatementFactory factory, + final StatementContextBase ctx, final Stream> declared, + final Stream> effective) { + // Statement reference count infrastructure makes an assumption that effective statement is only built after + // the declared statement is already done. Statements tracked by this class always have a declared view, and + // we need to ensure that is built before we touch effective substatements. + // + // Once the effective substatement stream has been exhausted, reference counting will triggers a sweep, hence + // the substatements may be gone by the time the factory attempts to acquire the declared statement. + ctx.declared(); + + return factory.createEffective(ctx, declared, effective); + } + + @Override + final E createInferredEffective(final StatementFactory factory, + final InferredStatementContext ctx, final Stream> declared, + final Stream> effective) { + return createEffective(factory, ctx, declared, effective); + } + /** * Create a new substatement at the specified offset. * @@ -175,71 +152,47 @@ abstract class AbstractResumedStatement, E ext checkState(inProgressPhase != ModelProcessingPhase.EFFECTIVE_MODEL, "Declared statement cannot be added in effective phase at: %s", sourceReference()); + final SubstatementContext ret; final var implicitParent = definition().getImplicitParentFor(this, def.getPublicView()); if (implicitParent.isPresent()) { - return createImplicitParent(offset, implicitParent.orElseThrow(), ref, argument) - .createSubstatement(0, def, ref, argument); + setImplicitDeclaredFlag(); + final var parent = createUndeclared(offset, implicitParent.orElseThrow(), ref, argument); + ret = new SubstatementContext<>(parent, def, ref, argument); + parent.addEffectiveSubstatement(ret); + } else { + ret = new SubstatementContext<>(this, def, ref, argument); + substatements = substatements.put(offset, ret); } - final AbstractResumedStatement ret = new SubstatementContext<>(this, def, ref, argument); - substatements = substatements.put(offset, ret); def.onStatementAdded(ret); return ret; } - @Override - final AbstractResumedStatement unmodifiedEffectiveSource() { - // This statement is comes from the source - return this; - } - - @Override - final boolean hasEmptySubstatements() { - return substatements.size() == 0 && effective.isEmpty(); - } - - @Override - final boolean noSensitiveSubstatements() { - return hasEmptySubstatements() - || noSensitiveSubstatements(substatements) && noSensitiveSubstatements(effective); - } - - @Override - final Iterable> effectiveChildrenToComplete() { - return effective; + private , Z extends EffectiveStatement> + UndeclaredStmtCtx createUndeclared(final int offset, final StatementSupport support, + final StatementSourceReference ref, final String argument) { + final UndeclaredStmtCtx ret; + final var implicitParent = definition().getImplicitParentFor(this, support.getPublicView()); + if (implicitParent.isPresent()) { + final var parent = createUndeclared(offset, implicitParent.orElseThrow(), ref, argument); + ret = new UndeclaredStmtCtx<>(parent, support, argument); + parent.addEffectiveSubstatement(ret); + } else { + ret = new UndeclaredStmtCtx<>(this, support, argument); + substatements = substatements.put(offset, ret); + } + support.onStatementAdded(ret); + return ret; } @Override final Stream> streamDeclared() { - return declaredSubstatements().stream().filter(StmtContext::isSupportedToBuildEffective); + return substatements.stream().filter(StmtContext::isSupportedToBuildEffective); } @Override - final Stream> streamEffective() { - return effective.stream().filter(StmtContext::isSupportedToBuildEffective); - } - - @Override - final void markNoParentRef() { - markNoParentRef(substatements); - markNoParentRef(effective); - } - - @Override - final int sweepSubstatements() { - // First we need to sweep all statements, which may trigger sweeps all across the place, for example: - // - 'effective' member sweeping a 'substatements' member - // - 'substatements' member sweeping a 'substatements' member which came before it during iteration - // We then iterate once again, counting what remains unswept - sweep(substatements); - sweep(effective); - final int count = countUnswept(substatements) + countUnswept(effective); - if (count != 0) { - LOG.debug("{} children left to sweep from {}", count, this); - } + final void dropDeclaredSubstatements() { substatements = null; - effective = null; - return count; } /** @@ -250,13 +203,17 @@ abstract class AbstractResumedStatement, E ext * @return Substatement, or null if substatement does not exist. */ final @Nullable AbstractResumedStatement enterSubstatement(final int offset) { - var ret = substatements.get(offset); - if (ret != null) { - while (ret.origin() == StatementOrigin.CONTEXT) { - ret = verifyNotNull(ret.substatements.get(0)); - } + final var stmt = substatements.get(offset); + return stmt == null ? null : unmaskUndeclared(stmt); + } + + private static @NonNull AbstractResumedStatement unmaskUndeclared(final ReactorStmtCtx stmt) { + var ret = stmt; + while (!(ret instanceof AbstractResumedStatement)) { + verify(ret instanceof UndeclaredStmtCtx, "Unexpectred statement %s", ret); + ret = ((UndeclaredStmtCtx) ret).getResumedSubstatement(); } - return ret; + return (AbstractResumedStatement) ret; } /** @@ -266,7 +223,7 @@ abstract class AbstractResumedStatement, E ext * @return Declared parent statement */ final @Nullable AbstractResumedStatement exitStatement(final ModelProcessingPhase phase) { - endDeclared(phase); + finishDeclaration(phase); final var parent = getParentContext(); if (parent == null) { return null; @@ -274,45 +231,33 @@ abstract class AbstractResumedStatement, E ext var ret = verifyParent(parent); // Unwind all undeclared statements - while (ret.origin() == StatementOrigin.CONTEXT) { - ret.endDeclared(phase); + while (!(ret instanceof AbstractResumedStatement)) { + ret.finishDeclaration(phase); ret = verifyParent(ret.getParentContext()); } - return ret; + return (AbstractResumedStatement) ret; } - // FIXME: AbstractResumedStatement should only ever have AbstractResumedStatement parents, which would remove the - // need for this method. In ordered to do that we need to untangle SubstatementContext's users and do not - // allow it being reparent()ed. - private static AbstractResumedStatement verifyParent(final StatementContextBase parent) { - verify(parent instanceof AbstractResumedStatement, "Unexpected parent context %s", parent); - return (AbstractResumedStatement) parent; + // FIXME: AbstractResumedStatement should only ever have OriginalStmtCtx parents, which would remove the need for + // this method. In ordered to do that we need to untangle SubstatementContext's users and do not allow it + // being reparent()ed. + private static OriginalStmtCtx verifyParent(final StatementContextBase parent) { + verify(parent instanceof OriginalStmtCtx, "Unexpected parent context %s", parent); + return (OriginalStmtCtx) parent; } final void resizeSubstatements(final int expectedSize) { substatements = substatements.ensureCapacity(expectedSize); } - final void walkChildren(final ModelProcessingPhase phase) { - checkState(isFullyDefined()); - substatements.forEach(stmt -> { - stmt.walkChildren(phase); - stmt.endDeclared(phase); - }); - } - - /** - * Ends declared section of current node for the specified phase. - * - * @param phase processing phase that ended - */ - final void endDeclared(final ModelProcessingPhase phase) { - definition().onDeclarationFinished(this, phase); + @Override + final void declarationFinished(final ModelProcessingPhase phase) { + finishChildrenDeclaration(phase); + finishDeclaration(phase); } - private AbstractResumedStatement createImplicitParent(final int offset, - final StatementSupport implicitParent, final StatementSourceReference ref, final String argument) { - return createSubstatement(offset, new StatementDefinitionContext<>(implicitParent), - ImplicitSubstatement.of(ref), argument); + private void finishChildrenDeclaration(final ModelProcessingPhase phase) { + checkState(isFullyDefined()); + substatements.forEach(stmt -> stmt.declarationFinished(phase)); } }