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=03d20e81d900b0adcbcb670e5501c6fdd2d061aa;hb=bc84355a85cafb4d8257a0e397c1efb2409aaf2e;hp=f5b33582799fafbab1d14b39e795f26ce64e21e1;hpb=fc17f39c478a20907bec485d1b9b38fdb9eba0c8;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 f5b3358279..03d20e81d9 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,29 +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.Iterator; -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 @@ -43,20 +34,16 @@ 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; + private boolean implicitDeclared; // Copy constructor AbstractResumedStatement(final AbstractResumedStatement original) { super(original); - this.statementDeclSource = original.statementDeclSource; this.rawArgument = original.rawArgument; this.substatements = original.substatements; this.declaredInstance = original.declaredInstance; @@ -64,33 +51,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; @@ -98,33 +62,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 @@ -140,9 +78,16 @@ abstract class AbstractResumedStatement, E ext return declaredInstance = definition().getFactory().createDeclared(this, substatementsAsDeclared()); } + @SuppressWarnings({ "rawtypes", "unchecked" }) private @NonNull Stream> substatementsAsDeclared() { - // FIXME: YANGTOOLS-1383: this stream includes implicit case statements, but it should not - return substatements.stream().map(AbstractResumedStatement::declared); + final Stream> stream; + if (implicitDeclared) { + stream = substatements.stream().map(AbstractResumedStatement::unmaskUndeclared); + } else { + stream = (Stream) substatements.stream(); + } + + return stream.map(AbstractResumedStatement::declared); } @Override @@ -152,7 +97,7 @@ abstract class AbstractResumedStatement, E ext @Override public final StatementSourceReference getSourceReference() { - return statementDeclSource; + return sourceReference(); } @Override @@ -160,6 +105,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. * @@ -181,71 +153,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); + implicitDeclared = true; + 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 Iterator> effectiveChildrenToComplete() { - return effective.iterator(); + 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 ImplicitStmtCtx<>(parent, support, argument); + parent.addEffectiveSubstatement(ret); + } else { + ret = new ImplicitStmtCtx<>(this, support, argument); + substatements = substatements.put(offset, ret); + } + support.onStatementAdded(ret); + return ret; } @Override final Stream> streamDeclared() { - return declaredSubstatements().stream().filter(StmtContext::isSupportedToBuildEffective); - } - - @Override - final Stream> streamEffective() { - return effective.stream().filter(StmtContext::isSupportedToBuildEffective); + return substatements.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; } /** @@ -256,13 +204,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; } /** @@ -280,25 +232,26 @@ abstract class AbstractResumedStatement, E ext var ret = verifyParent(parent); // Unwind all undeclared statements - while (ret.origin() == StatementOrigin.CONTEXT) { + 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); } + @Override final void declarationFinished(final ModelProcessingPhase phase) { finishChildrenDeclaration(phase); finishDeclaration(phase); @@ -308,19 +261,4 @@ abstract class AbstractResumedStatement, E ext checkState(isFullyDefined()); substatements.forEach(stmt -> stmt.declarationFinished(phase)); } - - /** - * Ends declared section of current node for the specified phase. - * - * @param phase processing phase that ended - */ - private void finishDeclaration(final ModelProcessingPhase phase) { - definition().onDeclarationFinished(this, 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); - } }