/* * Copyright (c) 2021 PANTHEON.tech, s.r.o. and others. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ package org.opendaylight.yangtools.yang.parser.stmt.reactor; 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.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.parser.spi.meta.CopyType; import org.opendaylight.yangtools.yang.parser.spi.meta.ModelProcessingPhase; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; import org.opendaylight.yangtools.yang.parser.spi.source.StatementSourceReference; import org.slf4j.Logger; import org.slf4j.LoggerFactory; abstract class OriginalStmtCtx, E extends EffectiveStatement> extends StatementContextBase { private static final Logger LOG = LoggerFactory.getLogger(OriginalStmtCtx.class); private final @NonNull StatementSourceReference ref; private List> effective = ImmutableList.of(); OriginalStmtCtx(final OriginalStmtCtx original) { super(original); this.ref = original.ref; } OriginalStmtCtx(final StatementDefinitionContext def, final StatementSourceReference ref) { super(def); this.ref = requireNonNull(ref); } OriginalStmtCtx(final StatementDefinitionContext def, final StatementSourceReference ref, final CopyType copyType) { super(def, copyType); this.ref = requireNonNull(ref); } @Override public final StatementSourceReference sourceReference() { return ref; } @Override public final Optional> getOriginalCtx() { return Optional.empty(); } @Override public final Optional> getPreviousCopyCtx() { return Optional.empty(); } @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); afterAddEffectiveSubstatement(substatement); } @Override final void addEffectiveSubstatementsImpl(final Collection> statements) { effective = addEffectiveSubstatementsImpl(effective, statements); } @Override final Iterator> effectiveChildrenToComplete() { return effective.iterator(); } @Override final Stream> streamEffective() { return effective.stream().filter(StmtContext::isSupportedToBuildEffective); } @Override final OriginalStmtCtx unmodifiedEffectiveSource() { // This statement is comes from the source return this; } @Override final boolean hasEmptySubstatements() { return effective.isEmpty() && mutableDeclaredSubstatements().isEmpty(); } @Override final boolean noSensitiveSubstatements() { return hasEmptySubstatements() || noSensitiveSubstatements(effective) && noSensitiveSubstatements(mutableDeclaredSubstatements()); } @Override final void markNoParentRef() { markNoParentRef(mutableDeclaredSubstatements()); 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 final var declared = mutableDeclaredSubstatements(); sweep(declared); sweep(effective); final int count = countUnswept(declared) + countUnswept(effective); if (count != 0) { LOG.debug("{} children left to sweep from {}", count, this); } effective = null; dropDeclaredSubstatements(); return count; } abstract void dropDeclaredSubstatements(); void declarationFinished(final ModelProcessingPhase phase) { finishDeclaration(phase); } /** * Ends declared section of current node for the specified phase. * * @param phase processing phase that ended */ final void finishDeclaration(final ModelProcessingPhase phase) { definition().onDeclarationFinished(this, phase); } final OriginalStmtCtx getResumedSubstatement() { final var local = verifyNotNull(effective); verify(!local.isEmpty(), "Unexpected empty statements"); final var ret = local.get(0); verify(ret instanceof OriginalStmtCtx, "Unexpected statement %s", ret); return (OriginalStmtCtx) ret; } }