import org.opendaylight.yangtools.yang.model.spi.meta.SubstatementIndexingException;
/**
- * Static entry point to instantiating {@link EffectiveStatement} covered in the {@code RFC7950} metamodel.
+ * Static entry point to instantiating declared {@link EffectiveStatement} covered in the {@code RFC7950} metamodel.
*/
@Beta
@NonNullByDefault
}
}
- public static CaseEffectiveStatement createCase(final QName argument, final int flags,
- final ImmutableList<? extends EffectiveStatement<?, ?>> substatements) {
- return new UndeclaredCaseEffectiveStatement(substatements, argument, flags);
- }
-
public static CaseEffectiveStatement createCase(final CaseStatement declared, final QName argument,
final int flags, final ImmutableList<? extends EffectiveStatement<?, ?>> substatements) {
return new DeclaredCaseEffectiveStatement(declared, substatements, argument, flags);
}
}
- public static InputEffectiveStatement createInput(final QName argument, final int flags,
- final ImmutableList<? extends EffectiveStatement<?, ?>> substatements)
- throws SubstatementIndexingException {
- return new UndeclaredInputEffectiveStatement(substatements, argument, flags);
- }
-
public static InputEffectiveStatement createInput(final InputStatement declared, final QName argument,
final int flags, final ImmutableList<? extends EffectiveStatement<?, ?>> substatements)
throws SubstatementIndexingException {
}
}
- public static OutputEffectiveStatement createOutput(final QName argument, final int flags,
- final ImmutableList<? extends EffectiveStatement<?, ?>> substatements)
- throws SubstatementIndexingException {
- return new UndeclaredOutputEffectiveStatement(substatements, argument, flags);
- }
-
public static OutputEffectiveStatement createOutput(final OutputStatement declared, final QName argument,
final int flags, final ImmutableList<? extends EffectiveStatement<?, ?>> substatements)
throws SubstatementIndexingException {
+++ /dev/null
-/*
- * Copyright (c) 2020 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.model.ri.stmt;
-
-import com.google.common.annotations.Beta;
-import com.google.common.collect.ImmutableList;
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
-import org.opendaylight.yangtools.yang.model.api.stmt.CaseStatement;
-import org.opendaylight.yangtools.yang.model.api.stmt.InputStatement;
-import org.opendaylight.yangtools.yang.model.api.stmt.OutputStatement;
-import org.opendaylight.yangtools.yang.model.ri.stmt.impl.decl.EmptyUndeclaredCaseStatement;
-import org.opendaylight.yangtools.yang.model.ri.stmt.impl.decl.EmptyUndeclaredInputStatement;
-import org.opendaylight.yangtools.yang.model.ri.stmt.impl.decl.EmptyUndeclaredOutputStatement;
-import org.opendaylight.yangtools.yang.model.ri.stmt.impl.decl.RegularUndeclaredCaseStatement;
-import org.opendaylight.yangtools.yang.model.ri.stmt.impl.decl.RegularUndeclaredInputStatement;
-import org.opendaylight.yangtools.yang.model.ri.stmt.impl.decl.RegularUndeclaredOutputStatement;
-
-/**
- * Static entry point to instantiating {@link DeclaredStatements} covered in the {@code RFC7950} metamodel which are
- * not really declared, but rather implicit.
- */
-@Beta
-@NonNullByDefault
-public final class ImplicitStatements {
- private ImplicitStatements() {
- // Hidden on purpose
- }
-
- public static CaseStatement createCase(final QName argument,
- final ImmutableList<? extends DeclaredStatement<?>> substatements) {
- return substatements.isEmpty() ? new EmptyUndeclaredCaseStatement(argument)
- : new RegularUndeclaredCaseStatement(argument, substatements);
- }
-
- public static InputStatement createInput(final QName argument,
- final ImmutableList<? extends DeclaredStatement<?>> substatements) {
- return substatements.isEmpty() ? new EmptyUndeclaredInputStatement(argument)
- : new RegularUndeclaredInputStatement(argument, substatements);
- }
-
- public static OutputStatement createOutput(final QName argument,
- final ImmutableList<? extends DeclaredStatement<?>> substatements) {
- return substatements.isEmpty() ? new EmptyUndeclaredOutputStatement(argument)
- : new RegularUndeclaredOutputStatement(argument, substatements);
- }
-}
--- /dev/null
+/*
+ * 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.model.ri.stmt;
+
+import com.google.common.annotations.Beta;
+import com.google.common.collect.ImmutableList;
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.CaseEffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.InputEffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.OutputEffectiveStatement;
+import org.opendaylight.yangtools.yang.model.ri.stmt.impl.eff.UndeclaredCaseEffectiveStatement;
+import org.opendaylight.yangtools.yang.model.ri.stmt.impl.eff.UndeclaredInputEffectiveStatement;
+import org.opendaylight.yangtools.yang.model.ri.stmt.impl.eff.UndeclaredOutputEffectiveStatement;
+import org.opendaylight.yangtools.yang.model.spi.meta.SubstatementIndexingException;
+
+/**
+ * Static entry point to instantiating undeclared {@link EffectiveStatement} covered in the {@code RFC7950} metamodel.
+ */
+@Beta
+@NonNullByDefault
+public final class UndeclaredStatements {
+ private UndeclaredStatements() {
+ // Hidden on purpose
+ }
+
+ public static CaseEffectiveStatement createCase(final QName argument, final int flags,
+ final ImmutableList<? extends EffectiveStatement<?, ?>> substatements) {
+ return new UndeclaredCaseEffectiveStatement(substatements, argument, flags);
+ }
+
+ public static InputEffectiveStatement createInput(final QName argument, final int flags,
+ final ImmutableList<? extends EffectiveStatement<?, ?>> substatements)
+ throws SubstatementIndexingException {
+ return new UndeclaredInputEffectiveStatement(substatements, argument, flags);
+ }
+
+ public static OutputEffectiveStatement createOutput(final QName argument, final int flags,
+ final ImmutableList<? extends EffectiveStatement<?, ?>> substatements)
+ throws SubstatementIndexingException {
+ return new UndeclaredOutputEffectiveStatement(substatements, argument, flags);
+ }
+}
import org.opendaylight.yangtools.yang.model.api.stmt.CaseStatement;
import org.opendaylight.yangtools.yang.model.spi.meta.AbstractDeclaredStatement.WithQNameArgument;
-public class EmptyCaseStatement extends WithQNameArgument implements CaseStatement {
+public final class EmptyCaseStatement extends WithQNameArgument implements CaseStatement {
public EmptyCaseStatement(final QName argument) {
super(argument);
}
import org.opendaylight.yangtools.yang.model.api.stmt.InputStatement;
import org.opendaylight.yangtools.yang.model.spi.meta.AbstractDeclaredStatement.WithQNameArgument;
-public class EmptyInputStatement extends WithQNameArgument implements InputStatement {
+public final class EmptyInputStatement extends WithQNameArgument implements InputStatement {
public EmptyInputStatement(final QName argument) {
super(argument);
}
import org.opendaylight.yangtools.yang.model.api.stmt.OutputStatement;
import org.opendaylight.yangtools.yang.model.spi.meta.AbstractDeclaredStatement.WithQNameArgument;
-public class EmptyOutputStatement extends WithQNameArgument implements OutputStatement {
+public final class EmptyOutputStatement extends WithQNameArgument implements OutputStatement {
public EmptyOutputStatement(final QName argument) {
super(argument);
}
+++ /dev/null
-/*
- * Copyright (c) 2020 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.model.ri.stmt.impl.decl;
-
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.model.api.meta.StatementOrigin;
-
-public final class EmptyUndeclaredCaseStatement extends EmptyCaseStatement {
- public EmptyUndeclaredCaseStatement(final QName argument) {
- super(argument);
- }
-
- @Override
- public StatementOrigin statementOrigin() {
- return StatementOrigin.CONTEXT;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2020 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.model.ri.stmt.impl.decl;
-
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.model.api.meta.StatementOrigin;
-
-public final class EmptyUndeclaredInputStatement extends EmptyInputStatement {
- public EmptyUndeclaredInputStatement(final QName argument) {
- super(argument);
- }
-
- @Override
- public StatementOrigin statementOrigin() {
- return StatementOrigin.CONTEXT;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2020 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.model.ri.stmt.impl.decl;
-
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.model.api.meta.StatementOrigin;
-
-public final class EmptyUndeclaredOutputStatement extends EmptyOutputStatement {
- public EmptyUndeclaredOutputStatement(final QName argument) {
- super(argument);
- }
-
- @Override
- public StatementOrigin statementOrigin() {
- return StatementOrigin.CONTEXT;
- }
-}
import org.opendaylight.yangtools.yang.model.api.stmt.CaseStatement;
import org.opendaylight.yangtools.yang.model.spi.meta.AbstractDeclaredStatement.WithQNameArgument.WithSubstatements;
-public class RegularCaseStatement extends WithSubstatements implements CaseStatement {
+public final class RegularCaseStatement extends WithSubstatements implements CaseStatement {
public RegularCaseStatement(final QName argument,
final ImmutableList<? extends DeclaredStatement<?>> substatements) {
super(argument, substatements);
import org.opendaylight.yangtools.yang.model.api.stmt.InputStatement;
import org.opendaylight.yangtools.yang.model.spi.meta.AbstractDeclaredStatement.WithQNameArgument.WithSubstatements;
-public class RegularInputStatement extends WithSubstatements implements InputStatement {
+public final class RegularInputStatement extends WithSubstatements implements InputStatement {
public RegularInputStatement(final QName argument,
final ImmutableList<? extends DeclaredStatement<?>> substatements) {
super(argument, substatements);
import org.opendaylight.yangtools.yang.model.api.stmt.OutputStatement;
import org.opendaylight.yangtools.yang.model.spi.meta.AbstractDeclaredStatement.WithQNameArgument.WithSubstatements;
-public class RegularOutputStatement extends WithSubstatements implements OutputStatement {
+public final class RegularOutputStatement extends WithSubstatements implements OutputStatement {
public RegularOutputStatement(final QName argument,
final ImmutableList<? extends DeclaredStatement<?>> substatements) {
super(argument, substatements);
+++ /dev/null
-/*
- * Copyright (c) 2020 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.model.ri.stmt.impl.decl;
-
-import com.google.common.collect.ImmutableList;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
-import org.opendaylight.yangtools.yang.model.api.meta.StatementOrigin;
-
-public final class RegularUndeclaredCaseStatement extends RegularCaseStatement {
- public RegularUndeclaredCaseStatement(final QName argument,
- final ImmutableList<? extends DeclaredStatement<?>> substatements) {
- super(argument, substatements);
- }
-
- @Override
- public StatementOrigin statementOrigin() {
- return StatementOrigin.CONTEXT;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2020 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.model.ri.stmt.impl.decl;
-
-import com.google.common.collect.ImmutableList;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
-import org.opendaylight.yangtools.yang.model.api.meta.StatementOrigin;
-
-public final class RegularUndeclaredInputStatement extends RegularInputStatement {
- public RegularUndeclaredInputStatement(final QName argument,
- final ImmutableList<? extends DeclaredStatement<?>> substatements) {
- super(argument, substatements);
- }
-
- @Override
- public StatementOrigin statementOrigin() {
- return StatementOrigin.CONTEXT;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2020 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.model.ri.stmt.impl.decl;
-
-import com.google.common.collect.ImmutableList;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
-import org.opendaylight.yangtools.yang.model.api.meta.StatementOrigin;
-
-public final class RegularUndeclaredOutputStatement extends RegularOutputStatement {
- public RegularUndeclaredOutputStatement(final QName argument,
- final ImmutableList<? extends DeclaredStatement<?>> substatements) {
- super(argument, substatements);
- }
-
- @Override
- public StatementOrigin statementOrigin() {
- return StatementOrigin.CONTEXT;
- }
-}
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
* @param <E> Effective Statement representation
*/
abstract class AbstractResumedStatement<A, D extends DeclaredStatement<A>, E extends EffectiveStatement<A, D>>
- extends StatementContextBase<A, D, E> implements ResumedStatement {
- private static final Logger LOG = LoggerFactory.getLogger(AbstractResumedStatement.class);
-
- private final @NonNull StatementSourceReference statementDeclSource;
+ extends OriginalStmtCtx<A, D, E> implements ResumedStatement {
private final String rawArgument;
- private List<ReactorStmtCtx<?, ?, ?>> effective = ImmutableList.of();
private StatementMap substatements = StatementMap.empty();
private @Nullable D declaredInstance;
// Copy constructor
AbstractResumedStatement(final AbstractResumedStatement<A, D, E> original) {
super(original);
- this.statementDeclSource = original.statementDeclSource;
this.rawArgument = original.rawArgument;
this.substatements = original.substatements;
this.declaredInstance = original.declaredInstance;
AbstractResumedStatement(final StatementDefinitionContext<A, D, E> 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<A, D, E> def, final StatementSourceReference ref,
- final String rawArgument, final CopyType copyType) {
- super(def, copyType);
- this.statementDeclSource = requireNonNull(ref);
- this.rawArgument = rawArgument;
- }
-
- @Override
- public final Optional<StmtContext<A, D, E>> getOriginalCtx() {
- return Optional.empty();
- }
-
- @Override
- public final Optional<StmtContext<A, D, E>> getPreviousCopyCtx() {
- return Optional.empty();
- }
-
- @Override
- public final StatementSourceReference sourceReference() {
- return statementDeclSource;
- }
-
@Override
public final String rawArgument() {
return rawArgument;
}
@Override
- public final Collection<? extends StatementContextBase<?, ?, ?>> mutableDeclaredSubstatements() {
- return substatements;
- }
-
- @Override
- public final Collection<? extends Mutable<?, ?, ?>> 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<? extends Mutable<?, ?, ?>> statements) {
- effective = addEffectiveSubstatementsImpl(effective, statements);
+ public Collection<? extends StatementContextBase<?, ?, ?>> mutableDeclaredSubstatements() {
+ return verifyNotNull(substatements);
}
@Override
return declaredInstance = definition().getFactory().createDeclared(this, substatementsAsDeclared());
}
+ @SuppressWarnings({ "rawtypes", "unchecked" })
private @NonNull Stream<DeclaredStatement<?>> substatementsAsDeclared() {
- var stream = substatements.stream();
+ final Stream<AbstractResumedStatement<?, ?, ?>> stream;
if (getImplicitDeclaredFlag()) {
- stream = stream.map(stmt -> {
- var ret = stmt;
- while (ret.origin() == StatementOrigin.CONTEXT) {
- final var stmts = ret.substatements;
- verify(stmts.size() == 1, "Unexpected substatements %s", stmts);
- ret = verifyNotNull(stmts.get(0));
- }
- return ret;
- });
+ stream = substatements.stream().map(AbstractResumedStatement::unmaskUndeclared);
+ } else {
+ stream = (Stream) substatements.stream();
}
return stream.map(AbstractResumedStatement::declared);
@Override
public final StatementSourceReference getSourceReference() {
- return statementDeclSource;
+ return sourceReference();
}
@Override
return fullyDefined();
}
+ @Override
+ final E createEffective(final StatementFactory<A, D, E> factory) {
+ return createEffective(factory, this);
+ }
+
+ // Creates EffectiveStatement through full materialization and assumes declared statement presence
+ private @NonNull E createEffective(final StatementFactory<A, D, E> factory,
+ final StatementContextBase<A, D, E> ctx) {
+ // 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.
+ declared();
+
+ return factory.createEffective(ctx, ctx.streamDeclared(), ctx.streamEffective());
+ }
+
+ @Override
+ final E createInferredEffective(final StatementFactory<A, D, E> factory,
+ final InferredStatementContext<A, D, E> ctx) {
+ return createEffective(factory, ctx);
+ }
+
/**
* Create a new substatement at the specified offset.
*
checkState(inProgressPhase != ModelProcessingPhase.EFFECTIVE_MODEL,
"Declared statement cannot be added in effective phase at: %s", sourceReference());
+ final SubstatementContext<X, Y, Z> 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<X, Y, Z> ret = new SubstatementContext<>(this, def, ref, argument);
- substatements = substatements.put(offset, ret);
def.onStatementAdded(ret);
return ret;
}
- @Override
- final AbstractResumedStatement<A, D, E> 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<ReactorStmtCtx<?, ?, ?>> effectiveChildrenToComplete() {
- return effective.iterator();
+ private <X, Y extends DeclaredStatement<X>, Z extends EffectiveStatement<X, Y>>
+ UndeclaredStmtCtx<X, Y, Z> createUndeclared(final int offset, final StatementSupport<X, Y, Z> support,
+ final StatementSourceReference ref, final String argument) {
+ final UndeclaredStmtCtx<X, Y, Z> 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
}
@Override
- final Stream<? extends @NonNull StmtContext<?, ?, ?>> 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;
}
/**
* @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));
- }
+ 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;
}
/**
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);
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) {
- setImplicitDeclaredFlag();
- return createSubstatement(offset, new StatementDefinitionContext<>(implicitParent),
- ImplicitSubstatement.of(ref), argument);
- }
}
--- /dev/null
+/*
+ * 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 java.util.Objects.requireNonNull;
+
+import com.google.common.collect.ForwardingObject;
+import java.util.Map;
+import java.util.Optional;
+import org.eclipse.jdt.annotation.NonNull;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.QNameModule;
+import org.opendaylight.yangtools.yang.common.YangVersion;
+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.CopyHistory;
+import org.opendaylight.yangtools.yang.parser.spi.meta.EffectiveStmtCtx.UndeclaredCurrent;
+import org.opendaylight.yangtools.yang.parser.spi.meta.ParserNamespace;
+import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
+import org.opendaylight.yangtools.yang.parser.spi.source.StatementSourceReference;
+
+final class ForwardingUndeclaredCurrent<A, D extends DeclaredStatement<A>> extends ForwardingObject
+ implements UndeclaredCurrent<A, D> {
+ private final Current<A, D> delegate;
+
+ ForwardingUndeclaredCurrent(final Current<A, D> delegate) {
+ this.delegate = requireNonNull(delegate);
+ }
+
+ @Override
+ public @NonNull QName moduleName() {
+ return delegate.moduleName();
+ }
+
+ @Override
+ @Deprecated(forRemoval = true)
+ public EffectiveStatement<?, ?> original() {
+ return delegate.original();
+ }
+
+ @Override
+ public QName argumentAsTypeQName() {
+ return delegate.argumentAsTypeQName();
+ }
+
+ @Override
+ @Deprecated
+ public <E extends EffectiveStatement<A, D>> StmtContext<A, D, E> caerbannog() {
+ return delegate.caerbannog();
+ }
+
+ @Override
+ public EffectiveConfig effectiveConfig() {
+ return delegate.effectiveConfig();
+ }
+
+ @Override
+ public QNameModule effectiveNamespace() {
+ return delegate.effectiveNamespace();
+ }
+
+ @Override
+ public Parent effectiveParent() {
+ return delegate.effectiveParent();
+ }
+
+ @Override
+ public StatementDefinition publicDefinition() {
+ return delegate.publicDefinition();
+ }
+
+ @Override
+ public StatementSourceReference sourceReference() {
+ return delegate.sourceReference();
+ }
+
+ @Override
+ public CopyHistory history() {
+ return delegate.history();
+ }
+
+ @Override
+ public <K, V, N extends ParserNamespace<K, V>> Map<K, V> namespace(final Class<@NonNull N> nsType) {
+ return delegate.namespace(nsType);
+ }
+
+ @Override
+ public <K, V, T extends K, N extends ParserNamespace<K, V>> V namespaceItem(final Class<@NonNull N> nsType,
+ final T key) {
+ return delegate.namespaceItem(nsType, key);
+ }
+
+ @Override
+ public <K, V, N extends ParserNamespace<K, V>> Map<K, V> localNamespacePortion(final Class<@NonNull N> nsType) {
+ return delegate.localNamespacePortion(nsType);
+ }
+
+ @Override
+ public A argument() {
+ return delegate.argument();
+ }
+
+ @Override
+ public YangVersion yangVersion() {
+ return delegate.yangVersion();
+ }
+
+ @Override
+ public <X, Z extends EffectiveStatement<X, ?>> Optional<X> findSubstatementArgument(final Class<Z> type) {
+ return delegate.findSubstatementArgument(type);
+ }
+
+ @Override
+ public boolean hasSubstatement(final Class<? extends EffectiveStatement<?, ?>> type) {
+ return delegate.hasSubstatement(type);
+ }
+
+ @Override
+ protected Current<A, D> delegate() {
+ return delegate;
+ }
+}
// If we have not materialized we do not have a difference in effective substatements, hence we can forward
// towards the source of the statement.
accessSubstatements();
- return substatements == null ? tryToReusePrototype(factory) : super.createEffective(factory);
+ return substatements == null ? tryToReusePrototype(factory) : createInferredEffective(factory, this);
}
- private @NonNull E tryToReusePrototype(final StatementFactory<A, D, E> factory) {
+ @Override
+ E createInferredEffective(final StatementFactory<A, D, E> factory, final InferredStatementContext<A, D, E> ctx) {
+ return prototype.createInferredEffective(factory, ctx);
+ }
+
+ private @NonNull E tryToReusePrototype(final @NonNull StatementFactory<A, D, E> factory) {
final E origEffective = prototype.buildEffective();
final Collection<? extends @NonNull EffectiveStatement<?, ?>> origSubstatements =
origEffective.effectiveSubstatements();
return internAlongCopyAxis(factory, factory.createEffective(this, declared.stream(), effective.stream()));
}
- private @NonNull E tryToReuseSubstatements(final StatementFactory<A, D, E> factory, final @NonNull E original) {
+ private @NonNull E tryToReuseSubstatements(final @NonNull StatementFactory<A, D, E> factory,
+ final @NonNull E original) {
if (allSubstatementsContextIndependent()) {
LOG.debug("Reusing substatements of: {}", prototype);
substatements = noRefs() ? REUSED_SUBSTATEMENTS : reusePrototypeReplicas();
// Fall back to full instantiation, which populates our substatements. Then check if we should be reusing
// the substatement list, as this operation turned out to not affect them.
- final E effective = super.createEffective(factory);
+ final E effective = createInferredEffective(factory, this);
// Since we have forced instantiation to deal with this case, we also need to reset the 'modified' flag
setUnmodified();
--- /dev/null
+/*
+ * 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<A, D extends DeclaredStatement<A>, E extends EffectiveStatement<A, D>>
+ extends StatementContextBase<A, D, E> {
+ private static final Logger LOG = LoggerFactory.getLogger(OriginalStmtCtx.class);
+
+ private final @NonNull StatementSourceReference ref;
+
+ private List<ReactorStmtCtx<?, ?, ?>> effective = ImmutableList.of();
+
+ OriginalStmtCtx(final OriginalStmtCtx<A, D, E> original) {
+ super(original);
+ this.ref = original.ref;
+ }
+
+ OriginalStmtCtx(final StatementDefinitionContext<A, D, E> def, final StatementSourceReference ref) {
+ super(def);
+ this.ref = requireNonNull(ref);
+ }
+
+ OriginalStmtCtx(final StatementDefinitionContext<A, D, E> 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<StmtContext<A, D, E>> getOriginalCtx() {
+ return Optional.empty();
+ }
+
+ @Override
+ public final Optional<StmtContext<A, D, E>> getPreviousCopyCtx() {
+ return Optional.empty();
+ }
+
+ @Override
+ public final Collection<? extends Mutable<?, ?, ?>> 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<? extends Mutable<?, ?, ?>> statements) {
+ effective = addEffectiveSubstatementsImpl(effective, statements);
+ }
+
+ @Override
+ final Iterator<ReactorStmtCtx<?, ?, ?>> effectiveChildrenToComplete() {
+ return effective.iterator();
+ }
+
+ @Override
+ final Stream<? extends @NonNull StmtContext<?, ?, ?>> streamEffective() {
+ return effective.stream().filter(StmtContext::isSupportedToBuildEffective);
+ }
+
+ @Override
+ final OriginalStmtCtx<A, D, E> 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;
+ }
+}
}
protected ToStringHelper addToStringAttributes(final ToStringHelper toStringHelper) {
- return toStringHelper.add("definition", definition()).add("rawArgument", rawArgument())
- .add("refCount", refString());
+ return toStringHelper.add("definition", definition()).add("argument", argument()).add("refCount", refString());
}
private String refString() {
}
private @NonNull E loadEffective() {
- // Creating an effective statement does not strictly require a declared instance -- there are statements like
- // 'input', which are implicitly defined.
- // Our implementation design makes an invariant assumption that buildDeclared() has been called by the time
- // we attempt to create effective statement:
- declared();
-
final E ret = createEffective();
effectiveInstance = ret;
// we have called createEffective(), substatements are no longer guarded by us. Let's see if we can clear up
@Override
public <X, Y extends DeclaredStatement<X>, Z extends EffectiveStatement<X, Y>>
- Mutable<X, Y, Z> addEffectiveSubstatement(final StatementSupport<X, Y, Z> support, final X arg) {
+ Mutable<X, Y, Z> addUndeclaredSubstatement(final StatementSupport<X, Y, Z> support, final X arg) {
throw new UnsupportedOperationException();
}
import org.opendaylight.yangtools.yang.parser.spi.meta.StatementSupport;
import org.opendaylight.yangtools.yang.parser.spi.meta.StatementSupport.CopyPolicy;
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.meta.UndeclaredStatementFactory;
import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
import org.opendaylight.yangtools.yang.parser.stmt.reactor.NamespaceBehaviourWithListeners.KeyedValueAddedListener;
import org.opendaylight.yangtools.yang.parser.stmt.reactor.NamespaceBehaviourWithListeners.PredicateValueAddedListener;
@Override
public final <X, Y extends DeclaredStatement<X>, Z extends EffectiveStatement<X, Y>>
- Mutable<X, Y, Z> addEffectiveSubstatement(final StatementSupport<X, Y, Z> support, final X arg) {
- // FIXME: YANGTOOLS-652: This does not need to be a SubstatementContext, in can be a specialized
- // StatementContextBase subclass.
- final Mutable<X, Y, Z> ret = new SubstatementContext<>(this, new StatementDefinitionContext<>(support),
- ImplicitSubstatement.of(sourceReference()), arg);
+ Mutable<X, Y, Z> addUndeclaredSubstatement(final StatementSupport<X, Y, Z> support, final X arg) {
+ requireNonNull(support);
+ checkArgument(support instanceof UndeclaredStatementFactory, "Unsupported statement support %s", support);
+
+ final var ret = new UndeclaredStmtCtx<>(this, support, arg);
support.onStatementAdded(ret);
addEffectiveSubstatement(ret);
return ret;
return result;
}
- @NonNull E createEffective(final StatementFactory<A, D, E> factory) {
- return createEffective(factory, this);
- }
+ abstract @NonNull E createEffective(@NonNull StatementFactory<A, D, E> factory);
- // Creates EffectiveStatement through full materialization
- static <A, D extends DeclaredStatement<A>, E extends EffectiveStatement<A, D>> @NonNull E createEffective(
- final StatementFactory<A, D, E> factory, final StatementContextBase<A, D, E> ctx) {
- return factory.createEffective(ctx, ctx.streamDeclared(), ctx.streamEffective());
- }
+ /**
+ * Routing of the request to build an effective statement from {@link InferredStatementContext} towards the original
+ * definition site. This is needed to pick the correct instantiation method: for declared statements we will
+ * eventually land in {@link AbstractResumedStatement}, for underclared statements that will be
+ * {@link UndeclaredStmtCtx}.
+ *
+ * @param factory Statement factory
+ * @param ctx Inferred statement context, i.e. where the effective statement is instantiated
+ * @return Built effective stateue
+ */
+ abstract @NonNull E createInferredEffective(@NonNull StatementFactory<A, D, E> factory,
+ @NonNull InferredStatementContext<A, D, E> ctx);
/**
* Return a stream of declared statements which can be built into an {@link EffectiveStatement}, as per
final InferredStatementContext<X, Y, Z> copy;
if (implicitParent.isPresent()) {
- final StatementDefinitionContext<?, ?, ?> def = new StatementDefinitionContext<>(implicitParent.get());
- result = new SubstatementContext(this, def, original.sourceReference(), original.rawArgument(),
- original.argument(), type);
+ result = new UndeclaredStmtCtx(this, implicitParent.orElseThrow(), original, type);
final CopyType childCopyType;
switch (type) {
return original;
}
- final StatementDefinitionContext<?, ?, ?> def = new StatementDefinitionContext<>(optImplicit.orElseThrow());
- final CopyType type = original.history().getLastOperation();
-
checkArgument(original instanceof StatementContextBase, "Unsupported original %s", original);
final var origBase = (StatementContextBase<?, ?, ?>)original;
- @SuppressWarnings({ "rawtypes", "unchecked"})
- final SubstatementContext<?, ?, ?> result = new SubstatementContext(origBase.getParentContext(), def,
- original.sourceReference(), original.rawArgument(), original.argument(), type);
-
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ final UndeclaredStmtCtx<?, ?, ?> result = new UndeclaredStmtCtx(origBase, optImplicit.orElseThrow());
result.addEffectiveSubstatement(origBase.reparent(result));
result.setCompletedPhase(original.getCompletedPhase());
return result;
*
* @author Robert Varga
*/
-abstract class StatementMap extends AbstractCollection<AbstractResumedStatement<?, ?, ?>> {
+abstract class StatementMap extends AbstractCollection<OriginalStmtCtx<?, ?, ?>> {
private static final class Empty extends StatementMap {
- private static final Iterator<AbstractResumedStatement<?, ?, ?>> EMPTY_ITERATOR;
+ private static final Iterator<OriginalStmtCtx<?, ?, ?>> EMPTY_ITERATOR;
static {
// This may look weird, but we really want to return two Iterator implementations from StatementMap, so that
// users have to deal with bimorphic invocation. Note that we want to invoke hasNext() here, as we want to
// initialize state to AbstractIterator.endOfData().
- final Iterator<AbstractResumedStatement<?, ?, ?>> it = new Regular(0).iterator();
+ final Iterator<OriginalStmtCtx<?, ?, ?>> it = new Regular(0).iterator();
verify(!it.hasNext());
EMPTY_ITERATOR = it;
}
}
@Override
- StatementMap put(final int index, final AbstractResumedStatement<?, ?, ?> obj) {
+ StatementMap put(final int index, final OriginalStmtCtx<?, ?, ?> obj) {
return index == 0 ? new Singleton(obj) : new Regular(index, obj);
}
}
@Override
- public void forEach(final Consumer<? super AbstractResumedStatement<?, ?, ?>> action) {
+ public void forEach(final Consumer<? super OriginalStmtCtx<?, ?, ?>> action) {
// No-op
}
@Override
- public Iterator<AbstractResumedStatement<?, ?, ?>> iterator() {
+ public Iterator<OriginalStmtCtx<?, ?, ?>> iterator() {
return EMPTY_ITERATOR;
}
}
private static final class Regular extends StatementMap {
- private AbstractResumedStatement<?, ?, ?>[] elements;
+ private OriginalStmtCtx<?, ?, ?>[] elements;
private int size;
Regular(final int expectedLimit) {
- elements = new AbstractResumedStatement<?, ?, ?>[expectedLimit];
+ elements = new OriginalStmtCtx<?, ?, ?>[expectedLimit];
}
- Regular(final int index, final AbstractResumedStatement<?, ?, ?> object) {
+ Regular(final int index, final OriginalStmtCtx<?, ?, ?> object) {
this(index + 1, index, object);
}
- Regular(final AbstractResumedStatement<?, ?, ?> object0, final int index,
- final AbstractResumedStatement<?, ?, ?> object) {
+ Regular(final OriginalStmtCtx<?, ?, ?> object0, final int index,
+ final OriginalStmtCtx<?, ?, ?> object) {
this(index + 1, 0, object0);
elements[index] = requireNonNull(object);
size = 2;
}
- Regular(final int expectedLimit, final int index, final AbstractResumedStatement<?, ?, ?> object) {
+ Regular(final int expectedLimit, final int index, final OriginalStmtCtx<?, ?, ?> object) {
this(expectedLimit);
elements[index] = requireNonNull(object);
size = 1;
}
@Override
- AbstractResumedStatement<?, ?, ?> get(final int index) {
+ OriginalStmtCtx<?, ?, ?> get(final int index) {
return index >= elements.length ? null : elements[index];
}
@Override
- StatementMap put(final int index, final AbstractResumedStatement<?, ?, ?> obj) {
+ StatementMap put(final int index, final OriginalStmtCtx<?, ?, ?> obj) {
if (index < elements.length) {
checkArgument(elements[index] == null);
} else {
}
@Override
- public Iterator<AbstractResumedStatement<?, ?, ?>> iterator() {
+ public Iterator<OriginalStmtCtx<?, ?, ?>> iterator() {
return new Iter(this);
}
- private static final class Iter extends AbstractIterator<AbstractResumedStatement<?, ?, ?>> {
+ private static final class Iter extends AbstractIterator<OriginalStmtCtx<?, ?, ?>> {
private int nextOffset = 0;
private Regular map;
}
@Override
- protected AbstractResumedStatement<?, ?, ?> computeNext() {
+ protected OriginalStmtCtx<?, ?, ?> computeNext() {
while (nextOffset < map.elements.length) {
- final AbstractResumedStatement<?, ?, ?> ret = map.elements[nextOffset++];
+ final OriginalStmtCtx<?, ?, ?> ret = map.elements[nextOffset++];
if (ret != null) {
return ret;
}
}
private static final class Singleton extends StatementMap {
- private final AbstractResumedStatement<?, ?, ?> object;
+ private final OriginalStmtCtx<?, ?, ?> object;
- Singleton(final AbstractResumedStatement<?, ?, ?> object) {
+ Singleton(final OriginalStmtCtx<?, ?, ?> object) {
this.object = requireNonNull(object);
}
@Override
- AbstractResumedStatement<?, ?, ?> get(final int index) {
+ OriginalStmtCtx<?, ?, ?> get(final int index) {
return index == 0 ? object : null;
}
@Override
- StatementMap put(final int index, final AbstractResumedStatement<?, ?, ?> obj) {
+ StatementMap put(final int index, final OriginalStmtCtx<?, ?, ?> obj) {
checkArgument(index != 0);
return new Regular(object, index, obj);
}
}
@Override
- public Iterator<AbstractResumedStatement<?, ?, ?>> iterator() {
+ public Iterator<OriginalStmtCtx<?, ?, ?>> iterator() {
return Iterators.singletonIterator(object);
}
}
* @param index Element index, must be non-negative
* @return Requested element or null if there is no element at that index
*/
- abstract @Nullable AbstractResumedStatement<?, ?, ?> get(int index);
+ abstract @Nullable OriginalStmtCtx<?, ?, ?> get(int index);
/**
* Add a statement at specified index.
* @return New statement map
* @throws IllegalArgumentException if the index is already occupied
*/
- abstract @NonNull StatementMap put(int index, @NonNull AbstractResumedStatement<?, ?, ?> obj);
+ abstract @NonNull StatementMap put(int index, @NonNull OriginalStmtCtx<?, ?, ?> obj);
/**
* Ensure storage space for at least {@code explectedLimit} substatements.
import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
-import org.opendaylight.yangtools.yang.parser.spi.meta.CopyType;
import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.StorageNodeType;
import org.opendaylight.yangtools.yang.parser.spi.source.StatementSourceReference;
private SubstatementContext(final SubstatementContext<A, D, E> original,
final StatementContextBase<?, ?, ?> parent) {
super(original);
- this.parent = requireNonNull(parent, "Parent must not be null");
+ this.parent = requireNonNull(parent);
this.argument = original.argument;
}
- SubstatementContext(final StatementContextBase<?, ?, ?> parent, final StatementDefinitionContext<A, D, E> def,
+ SubstatementContext(final OriginalStmtCtx<?, ?, ?> parent, final StatementDefinitionContext<A, D, E> def,
final StatementSourceReference ref, final String rawArgument) {
super(def, ref, rawArgument);
- this.parent = requireNonNull(parent, "Parent must not be null");
+ this.parent = requireNonNull(parent);
this.argument = def.parseArgumentValue(this, rawArgument());
}
- SubstatementContext(final StatementContextBase<?, ?, ?> parent, final StatementDefinitionContext<A, D, E> def,
- final StatementSourceReference ref, final A argument) {
- super(def, ref, null);
- this.parent = requireNonNull(parent, "Parent must not be null");
- this.argument = argument != null ? argument : def.parseArgumentValue(this, null);
- }
-
- // FIXME: YANGTOOLS-784: this constructor is only called in contexts where a different implementation
- // would be more appropriate
- SubstatementContext(final StatementContextBase<?, ?, ?> parent, final StatementDefinitionContext<A, D, E> def,
- final StatementSourceReference ref, final String rawArgument, final A argument, final CopyType copyType) {
- super(def, ref, rawArgument, copyType);
- this.parent = requireNonNull(parent, "Parent must not be null");
- this.argument = argument;
- }
-
@Override
SubstatementContext<A, D, E> reparent(final StatementContextBase<?, ?, ?> newParent) {
return new SubstatementContext<>(this, newParent);
--- /dev/null
+/*
+ * 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 java.util.Objects.requireNonNull;
+
+import com.google.common.collect.ImmutableList;
+import java.util.Collection;
+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.parser.spi.meta.CopyType;
+import org.opendaylight.yangtools.yang.parser.spi.meta.EffectiveStmtCtx.UndeclaredCurrent;
+import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.StorageNodeType;
+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.meta.UndeclaredStatementFactory;
+import org.opendaylight.yangtools.yang.parser.spi.source.ImplicitSubstatement;
+
+/**
+/**
+ * Core reactor statement implementation of {@link Mutable}.
+ *
+ * @param <A> Argument type
+ * @param <D> Declared Statement representation
+ * @param <E> Effective Statement representation
+ */
+final class UndeclaredStmtCtx<A, D extends DeclaredStatement<A>, E extends EffectiveStatement<A, D>>
+ extends OriginalStmtCtx<A, D, E> implements UndeclaredCurrent<A, D> {
+ private final StatementContextBase<?, ?, ?> parent;
+ private final A argument;
+
+ private UndeclaredStmtCtx(final UndeclaredStmtCtx<A, D, E> original, final StatementContextBase<?, ?, ?> parent) {
+ super(original);
+ this.parent = requireNonNull(parent);
+ this.argument = original.argument;
+ }
+
+ UndeclaredStmtCtx(final StatementContextBase<?, ?, ?> parent, final StatementSupport<A, D, E> support,
+ final @Nullable A argument) {
+ super(new StatementDefinitionContext<>(support), ImplicitSubstatement.of(parent.sourceReference()));
+ this.parent = requireNonNull(parent);
+ this.argument = argument != null ? argument : definition().parseArgumentValue(this, null);
+ }
+
+ // Exposed for StatementContextBase.wrapWithImplicit()
+ UndeclaredStmtCtx(final StatementContextBase<?, ?, ?> original, final StatementSupport<A, D, E> support) {
+ super(new StatementDefinitionContext<>(verifySupport(support)), original.sourceReference(),
+ original.getLastOperation());
+ this.parent = original.getParentContext();
+ this.argument = castArgument(original);
+ }
+
+ // Exposed for implicit substatement wrapping in StatementContextBase.childCopyOf()
+ UndeclaredStmtCtx(final StatementContextBase<?, ?, ?> parent, final StatementSupport<A, D, E> support,
+ final StatementContextBase<?, ?, ?> original, final CopyType type) {
+ super(new StatementDefinitionContext<>(verifySupport(support)), original.sourceReference(), type);
+ this.parent = requireNonNull(parent);
+ this.argument = castArgument(original);
+ }
+
+ // Exposed for AbstractResumedStatement
+ UndeclaredStmtCtx(final StatementContextBase<?, ?, ?> parent, final StatementSupport<A, D, E> support,
+ final String rawArgument) {
+ super(new StatementDefinitionContext<>(support), ImplicitSubstatement.of(parent.sourceReference()));
+ this.parent = requireNonNull(parent);
+ this.argument = definition().parseArgumentValue(this, rawArgument);
+ }
+
+ // FIXME: this assumes original's argument type matches this type... which is true for the only case we
+ // currently care about (implicit case in choice, which is always triggered by a SchemaTree original),
+ // but this will need re-visiting
+ @SuppressWarnings("unchecked")
+ private static <A> @NonNull A castArgument(final StatementContextBase<?, ?, ?> original) {
+ return (A) original.getArgument();
+ }
+
+ private static <T> T verifySupport(final T support) {
+ verify(support instanceof UndeclaredStatementFactory, "Unexpected statement support %s", support);
+ return support;
+ }
+
+ @Override
+ public Collection<? extends StatementContextBase<?, ?, ?>> mutableDeclaredSubstatements() {
+ return ImmutableList.of();
+ }
+
+ @Override
+ Stream<? extends @NonNull StmtContext<?, ?, ?>> streamDeclared() {
+ return Stream.empty();
+ }
+
+ @Override
+ void dropDeclaredSubstatements() {
+ // No-op
+ }
+
+ @Override
+ UndeclaredStmtCtx<A, D, E> reparent(final StatementContextBase<?, ?, ?> newParent) {
+ return new UndeclaredStmtCtx<>(this, newParent);
+ }
+
+ @Override
+ E createEffective(final StatementFactory<A, D, E> factory) {
+ return createEffective(factory, this, streamEffective());
+ }
+
+ @SuppressWarnings("unchecked")
+ private static <A, D extends DeclaredStatement<A>, E extends EffectiveStatement<A, D>> @NonNull E createEffective(
+ final @NonNull StatementFactory<A, D, E> factory, final @NonNull UndeclaredCurrent<A, D> ctx,
+ final @NonNull Stream<? extends StmtContext<?, ?, ?>> substatements) {
+ verify(factory instanceof UndeclaredStatementFactory, "Unexpected factory %s", factory);
+ return ((UndeclaredStatementFactory<A, D, E>) factory).createUndeclaredEffective(ctx, substatements);
+ }
+
+ @Override
+ E createInferredEffective(final StatementFactory<A, D, E> factory, final InferredStatementContext<A, D, E> ctx) {
+ return createEffective(factory, new ForwardingUndeclaredCurrent<>(ctx), ctx.streamEffective());
+ }
+
+ /*
+ * KEEP THINGS ORGANIZED!
+ *
+ * below methods exist in the same form in InferredStatementContext. If any adjustment is made here, make sure it is
+ * properly updated there.
+ */
+ @Override
+ public A argument() {
+ return argument;
+ }
+
+ @Override
+ public StatementContextBase<?, ?, ?> getParentContext() {
+ return parent;
+ }
+
+ @Override
+ public StorageNodeType getStorageNodeType() {
+ return StorageNodeType.STATEMENT_LOCAL;
+ }
+
+ @Override
+ public StatementContextBase<?, ?, ?> getParentNamespaceStorage() {
+ return parent;
+ }
+
+ @Override
+ public RootStatementContext<?, ?, ?> getRoot() {
+ return parent.getRoot();
+ }
+
+ @Override
+ public EffectiveConfig effectiveConfig() {
+ return effectiveConfig(parent);
+ }
+
+ @Override
+ protected boolean isIgnoringIfFeatures() {
+ return isIgnoringIfFeatures(parent);
+ }
+
+ @Override
+ protected boolean isIgnoringConfig() {
+ return isIgnoringConfig(parent);
+ }
+
+ @Override
+ protected boolean isParentSupportedByFeatures() {
+ return parent.isSupportedByFeatures();
+ }
+}
import static java.util.Objects.requireNonNull;
import com.google.common.collect.ImmutableList;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
import org.eclipse.jdt.annotation.NonNull;
import org.opendaylight.yangtools.yang.common.QName;
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.model.api.stmt.SchemaTreeEffectiveStatement;
import org.opendaylight.yangtools.yang.parser.api.YangParserConfiguration;
import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractSchemaTreeStatementSupport;
-import org.opendaylight.yangtools.yang.parser.spi.meta.EffectiveStmtCtx.Current;
+import org.opendaylight.yangtools.yang.parser.spi.meta.EffectiveStmtCtx.UndeclaredCurrent;
+import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
import org.opendaylight.yangtools.yang.parser.spi.meta.SubstatementValidator;
+import org.opendaylight.yangtools.yang.parser.spi.meta.UndeclaredStatementFactory;
/**
* A massively-misnamed superclass for statements which are both schema tree participants and can be created as implicit
* @param <E> Effective Statement representation
*/
abstract class AbstractImplicitStatementSupport<D extends DeclaredStatement<QName>,
- E extends SchemaTreeEffectiveStatement<D>> extends AbstractSchemaTreeStatementSupport<D, E> {
+ E extends SchemaTreeEffectiveStatement<D>> extends AbstractSchemaTreeStatementSupport<D, E>
+ implements UndeclaredStatementFactory<QName, D, E> {
AbstractImplicitStatementSupport(final StatementDefinition publicDefinition, final StatementPolicy<QName, D> policy,
final YangParserConfiguration config, final SubstatementValidator validator) {
super(publicDefinition, policy, config, requireNonNull(validator));
}
@Override
- public final E copyEffective(final Current<QName, D> stmt, final E original) {
- final StatementOrigin source = stmt.origin();
- switch (source) {
- case CONTEXT:
- return copyUndeclaredEffective(stmt, original);
- case DECLARATION:
- return copyDeclaredEffective(stmt, original);
- default:
- throw new IllegalStateException("Unhandled statement source " + source);
- }
+ public final E createUndeclaredEffective(final UndeclaredCurrent<QName, D> stmt,
+ final @NonNull Stream<? extends StmtContext<?, ?, ?>> effectiveSubstatements) {
+ return createUndeclaredEffective(stmt, buildEffectiveSubstatements(stmt,
+ statementsToBuild(stmt, effectiveSubstatements
+ .filter(StmtContext::isSupportedToBuildEffective)
+ .collect(Collectors.toUnmodifiableList()))));
}
- @Override
- protected E createEffective(final Current<QName, D> stmt,
- final ImmutableList<? extends EffectiveStatement<?, ?>> substatements) {
- final StatementOrigin origin = stmt.origin();
- switch (origin) {
- case CONTEXT:
- return createUndeclaredEffective(stmt, substatements);
- case DECLARATION:
- return createDeclaredEffective(stmt, substatements);
- default:
- throw new IllegalStateException("Unhandled statement origin " + origin);
- }
- }
-
- abstract @NonNull E copyDeclaredEffective(@NonNull Current<QName, D> stmt, @NonNull E original);
-
- abstract @NonNull E copyUndeclaredEffective(@NonNull Current<QName, D> stmt, @NonNull E original);
-
- abstract @NonNull E createDeclaredEffective(@NonNull Current<QName, D> stmt,
- @NonNull ImmutableList<? extends EffectiveStatement<?, ?>> substatements);
-
- abstract @NonNull E createUndeclaredEffective(@NonNull Current<QName, D> stmt,
- @NonNull ImmutableList<? extends EffectiveStatement<?, ?>> substatements);
+ abstract @NonNull E createUndeclaredEffective(@NonNull UndeclaredCurrent<QName, D> stmt,
+ @NonNull ImmutableList<? extends EffectiveStatement<?, ?>> substatements);
}
import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractQNameStatementSupport;
import org.opendaylight.yangtools.yang.parser.spi.meta.EffectiveStatementState;
import org.opendaylight.yangtools.yang.parser.spi.meta.EffectiveStmtCtx.Current;
+import org.opendaylight.yangtools.yang.parser.spi.meta.EffectiveStmtCtx.UndeclaredCurrent;
import org.opendaylight.yangtools.yang.parser.spi.meta.QNameWithFlagsEffectiveStatementState;
import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils;
}
@Override
- final @NonNull E copyDeclaredEffective(final Current<QName, D> stmt, final E original) {
- return copyDeclaredEffective(
- EffectiveStmtUtils.historyAndStatusFlags(stmt.history(), original.effectiveSubstatements()), stmt,
- original);
- }
-
- abstract @NonNull E copyDeclaredEffective(int flags, @NonNull Current<QName, D> stmt,
- @NonNull E original);
-
- @Override
- final @NonNull E copyUndeclaredEffective(final Current<QName, D> stmt, final E original) {
- return copyUndeclaredEffective(
- EffectiveStmtUtils.historyAndStatusFlags(stmt.history(), original.effectiveSubstatements()), stmt,
- original);
- }
-
- abstract @NonNull E copyUndeclaredEffective(int flags, @NonNull Current<QName, D> stmt, @NonNull E original);
-
- @Override
- final @NonNull E createDeclaredEffective(final Current<QName, D> stmt,
+ protected final E createEffective(final Current<QName, D> stmt,
final ImmutableList<? extends EffectiveStatement<?, ?>> substatements) {
try {
- return createDeclaredEffective(
- EffectiveStmtUtils.historyAndStatusFlags(stmt.history(), substatements), stmt, substatements);
+ return createEffective(EffectiveStmtUtils.historyAndStatusFlags(stmt.history(), substatements), stmt,
+ substatements);
} catch (SubstatementIndexingException e) {
throw new SourceException(e.getMessage(), stmt, e);
}
}
- abstract @NonNull E createDeclaredEffective(int flags, @NonNull Current<QName, D> stmt,
+ abstract @NonNull E createEffective(int flags, @NonNull Current<QName, D> stmt,
@NonNull ImmutableList<? extends EffectiveStatement<?, ?>> substatements);
@Override
- final E createUndeclaredEffective(final Current<QName, D> stmt,
+ public final @NonNull E copyEffective(final Current<QName, D> stmt, final E original) {
+ return copyEffective(
+ EffectiveStmtUtils.historyAndStatusFlags(stmt.history(), original.effectiveSubstatements()), stmt,
+ original);
+ }
+
+ abstract @NonNull E copyEffective(int flags, @NonNull Current<QName, D> stmt, @NonNull E original);
+
+ @Override
+ final E createUndeclaredEffective(final UndeclaredCurrent<QName, D> stmt,
final ImmutableList<? extends EffectiveStatement<?, ?>> substatements) {
return createUndeclaredEffective(EffectiveStmtUtils.historyAndStatusFlags(stmt.history(), substatements), stmt,
substatements);
}
- abstract @NonNull E createUndeclaredEffective(int flags, @NonNull Current<QName, D> stmt,
+ abstract @NonNull E createUndeclaredEffective(int flags, @NonNull UndeclaredCurrent<QName, D> stmt,
@NonNull ImmutableList<? extends EffectiveStatement<?, ?>> substatements);
@Override
private static void appendImplicitSubstatement(final Mutable<QName, ActionStatement, ActionEffectiveStatement> stmt,
final QName substatementName) {
- stmt.addEffectiveSubstatement(
+ stmt.addUndeclaredSubstatement(
verifyNotNull(stmt.getFromNamespace(StatementSupportNamespace.class, substatementName)), null);
}
}
import org.opendaylight.yangtools.yang.model.api.meta.DeclarationReference;
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.StatementOrigin;
import org.opendaylight.yangtools.yang.model.api.stmt.CaseEffectiveStatement;
import org.opendaylight.yangtools.yang.model.api.stmt.CaseStatement;
import org.opendaylight.yangtools.yang.model.api.stmt.StatusEffectiveStatement;
import org.opendaylight.yangtools.yang.model.ri.stmt.DeclaredStatementDecorators;
import org.opendaylight.yangtools.yang.model.ri.stmt.DeclaredStatements;
import org.opendaylight.yangtools.yang.model.ri.stmt.EffectiveStatements;
-import org.opendaylight.yangtools.yang.model.ri.stmt.ImplicitStatements;
+import org.opendaylight.yangtools.yang.model.ri.stmt.UndeclaredStatements;
import org.opendaylight.yangtools.yang.model.spi.meta.EffectiveStatementMixins.EffectiveStatementWithFlags.FlagsBuilder;
import org.opendaylight.yangtools.yang.model.spi.meta.SubstatementIndexingException;
import org.opendaylight.yangtools.yang.parser.api.YangParserConfiguration;
import org.opendaylight.yangtools.yang.parser.spi.meta.EffectiveStatementState;
import org.opendaylight.yangtools.yang.parser.spi.meta.EffectiveStmtCtx.Current;
import org.opendaylight.yangtools.yang.parser.spi.meta.EffectiveStmtCtx.Parent.EffectiveConfig;
+import org.opendaylight.yangtools.yang.parser.spi.meta.EffectiveStmtCtx.UndeclaredCurrent;
import org.opendaylight.yangtools.yang.parser.spi.meta.QNameWithFlagsEffectiveStatementState;
import org.opendaylight.yangtools.yang.parser.spi.meta.SubstatementValidator;
import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
@Override
protected CaseStatement createDeclared(final BoundStmtCtx<QName> ctx,
final ImmutableList<DeclaredStatement<?>> substatements) {
- final StatementOrigin origin = ctx.origin();
- switch (origin) {
- case CONTEXT:
- return ImplicitStatements.createCase(ctx.getArgument(), substatements);
- case DECLARATION:
- return DeclaredStatements.createCase(ctx.getArgument(), substatements);
- default:
- throw new IllegalStateException("Unhandled statement origin " + origin);
- }
+ return DeclaredStatements.createCase(ctx.getArgument(), substatements);
}
@Override
}
@Override
- protected CaseEffectiveStatement copyDeclaredEffective(final Current<QName, CaseStatement> stmt,
- final CaseEffectiveStatement original) {
- return EffectiveStatements.copyCase(original, stmt.getArgument(),
- computeFlags(stmt, original.effectiveSubstatements()));
- }
-
- @Override
- protected CaseEffectiveStatement copyUndeclaredEffective(final Current<QName, CaseStatement> stmt,
- final CaseEffectiveStatement original) {
- return EffectiveStatements.copyCase(original, stmt.getArgument(),
- computeFlags(stmt, original.effectiveSubstatements()));
- }
-
- @Override
- protected CaseEffectiveStatement createDeclaredEffective(final Current<QName, CaseStatement> stmt,
+ protected CaseEffectiveStatement createEffective(final Current<QName, CaseStatement> stmt,
final ImmutableList<? extends EffectiveStatement<?, ?>> substatements) {
try {
return EffectiveStatements.createCase(stmt.declared(), stmt.getArgument(),
}
@Override
- protected CaseEffectiveStatement createUndeclaredEffective(final Current<QName, CaseStatement> stmt,
+ public CaseEffectiveStatement copyEffective(final Current<QName, CaseStatement> stmt,
+ final CaseEffectiveStatement original) {
+ return EffectiveStatements.copyCase(original, stmt.getArgument(),
+ computeFlags(stmt, original.effectiveSubstatements()));
+ }
+
+ @Override
+ protected CaseEffectiveStatement createUndeclaredEffective(final UndeclaredCurrent<QName, CaseStatement> stmt,
final ImmutableList<? extends EffectiveStatement<?, ?>> substatements) {
try {
- return EffectiveStatements.createCase(stmt.getArgument(), computeFlags(stmt, substatements), substatements);
+ return UndeclaredStatements.createCase(stmt.getArgument(), computeFlags(stmt, substatements),
+ substatements);
} catch (SubstatementIndexingException e) {
throw new SourceException(e.getMessage(), stmt, e);
}
import org.opendaylight.yangtools.yang.model.api.meta.DeclarationReference;
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.StatementOrigin;
import org.opendaylight.yangtools.yang.model.api.stmt.InputEffectiveStatement;
import org.opendaylight.yangtools.yang.model.api.stmt.InputStatement;
import org.opendaylight.yangtools.yang.model.ri.stmt.DeclaredStatementDecorators;
import org.opendaylight.yangtools.yang.model.ri.stmt.DeclaredStatements;
import org.opendaylight.yangtools.yang.model.ri.stmt.EffectiveStatements;
-import org.opendaylight.yangtools.yang.model.ri.stmt.ImplicitStatements;
+import org.opendaylight.yangtools.yang.model.ri.stmt.UndeclaredStatements;
import org.opendaylight.yangtools.yang.model.spi.meta.SubstatementIndexingException;
import org.opendaylight.yangtools.yang.parser.api.YangParserConfiguration;
import org.opendaylight.yangtools.yang.parser.spi.meta.BoundStmtCtx;
import org.opendaylight.yangtools.yang.parser.spi.meta.EffectiveStmtCtx.Current;
+import org.opendaylight.yangtools.yang.parser.spi.meta.EffectiveStmtCtx.UndeclaredCurrent;
import org.opendaylight.yangtools.yang.parser.spi.meta.SubstatementValidator;
import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
@Override
protected InputStatement createDeclared(final BoundStmtCtx<QName> ctx,
final ImmutableList<DeclaredStatement<?>> substatements) {
- final StatementOrigin origin = ctx.origin();
- switch (origin) {
- case CONTEXT:
- return ImplicitStatements.createInput(ctx.getArgument(), substatements);
- case DECLARATION:
- return DeclaredStatements.createInput(ctx.getArgument(), substatements);
- default:
- throw new IllegalStateException("Unhandled statement origin " + origin);
- }
+ return DeclaredStatements.createInput(ctx.getArgument(), substatements);
}
@Override
}
@Override
- InputEffectiveStatement copyDeclaredEffective(final int flags, final Current<QName, InputStatement> stmt,
- final InputEffectiveStatement original) {
- return EffectiveStatements.copyInput(original, stmt.getArgument(), flags);
- }
-
- @Override
- InputEffectiveStatement copyUndeclaredEffective(final int flags, final Current<QName, InputStatement> stmt,
+ InputEffectiveStatement copyEffective(final int flags, final Current<QName, InputStatement> stmt,
final InputEffectiveStatement original) {
return EffectiveStatements.copyInput(original, stmt.getArgument(), flags);
}
@Override
- InputEffectiveStatement createDeclaredEffective(final int flags, final Current<QName, InputStatement> stmt,
+ InputEffectiveStatement createEffective(final int flags, final Current<QName, InputStatement> stmt,
final ImmutableList<? extends EffectiveStatement<?, ?>> substatements) {
try {
return EffectiveStatements.createInput(stmt.declared(), stmt.getArgument(), flags, substatements);
}
@Override
- InputEffectiveStatement createUndeclaredEffective(final int flags, final Current<QName, InputStatement> stmt,
+ InputEffectiveStatement createUndeclaredEffective(final int flags,
+ final UndeclaredCurrent<QName, InputStatement> stmt,
final ImmutableList<? extends EffectiveStatement<?, ?>> substatements) {
try {
- return EffectiveStatements.createInput(stmt.getArgument(), flags, substatements);
+ return UndeclaredStatements.createInput(stmt.getArgument(), flags, substatements);
} catch (SubstatementIndexingException e) {
throw new SourceException(e.getMessage(), stmt, e);
}
import org.opendaylight.yangtools.yang.model.api.meta.DeclarationReference;
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.StatementOrigin;
import org.opendaylight.yangtools.yang.model.api.stmt.OutputEffectiveStatement;
import org.opendaylight.yangtools.yang.model.api.stmt.OutputStatement;
import org.opendaylight.yangtools.yang.model.ri.stmt.DeclaredStatementDecorators;
import org.opendaylight.yangtools.yang.model.ri.stmt.DeclaredStatements;
import org.opendaylight.yangtools.yang.model.ri.stmt.EffectiveStatements;
-import org.opendaylight.yangtools.yang.model.ri.stmt.ImplicitStatements;
+import org.opendaylight.yangtools.yang.model.ri.stmt.UndeclaredStatements;
import org.opendaylight.yangtools.yang.model.spi.meta.SubstatementIndexingException;
import org.opendaylight.yangtools.yang.parser.api.YangParserConfiguration;
import org.opendaylight.yangtools.yang.parser.spi.meta.BoundStmtCtx;
import org.opendaylight.yangtools.yang.parser.spi.meta.EffectiveStmtCtx.Current;
+import org.opendaylight.yangtools.yang.parser.spi.meta.EffectiveStmtCtx.UndeclaredCurrent;
import org.opendaylight.yangtools.yang.parser.spi.meta.SubstatementValidator;
import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
@Override
protected OutputStatement createDeclared(final BoundStmtCtx<QName> ctx,
final ImmutableList<DeclaredStatement<?>> substatements) {
- final StatementOrigin origin = ctx.origin();
- switch (origin) {
- case CONTEXT:
- return ImplicitStatements.createOutput(ctx.getArgument(), substatements);
- case DECLARATION:
- return DeclaredStatements.createOutput(ctx.getArgument(), substatements);
- default:
- throw new IllegalStateException("Unhandled statement origin " + origin);
- }
+ return DeclaredStatements.createOutput(ctx.getArgument(), substatements);
}
@Override
}
@Override
- OutputEffectiveStatement copyDeclaredEffective(final int flags, final Current<QName, OutputStatement> stmt,
- final OutputEffectiveStatement original) {
- return EffectiveStatements.copyOutput(original, stmt.getArgument(), flags);
- }
-
- @Override
- OutputEffectiveStatement copyUndeclaredEffective(final int flags, final Current<QName, OutputStatement> stmt,
+ OutputEffectiveStatement copyEffective(final int flags, final Current<QName, OutputStatement> stmt,
final OutputEffectiveStatement original) {
return EffectiveStatements.copyOutput(original, stmt.getArgument(), flags);
}
@Override
- OutputEffectiveStatement createDeclaredEffective(final int flags, final Current<QName, OutputStatement> stmt,
+ OutputEffectiveStatement createEffective(final int flags, final Current<QName, OutputStatement> stmt,
final ImmutableList<? extends EffectiveStatement<?, ?>> substatements) {
try {
return EffectiveStatements.createOutput(stmt.declared(), stmt.getArgument(), flags, substatements);
}
@Override
- OutputEffectiveStatement createUndeclaredEffective(final int flags, final Current<QName, OutputStatement> stmt,
+ OutputEffectiveStatement createUndeclaredEffective(final int flags,
+ final UndeclaredCurrent<QName, OutputStatement> stmt,
final ImmutableList<? extends EffectiveStatement<?, ?>> substatements) {
try {
- return EffectiveStatements.createOutput(stmt.getArgument(), flags, substatements);
+ return UndeclaredStatements.createOutput(stmt.getArgument(), flags, substatements);
} catch (SubstatementIndexingException e) {
throw new SourceException(e.getMessage(), stmt, e);
}
private static void appendImplicitSubstatement(final Mutable<QName, RpcStatement, RpcEffectiveStatement> stmt,
final QName substatementName) {
- stmt.addEffectiveSubstatement(
+ stmt.addUndeclaredSubstatement(
verifyNotNull(stmt.getFromNamespace(StatementSupportNamespace.class, substatementName)), null);
}
}
@Deprecated
<E extends EffectiveStatement<A, D>> @NonNull StmtContext<A, D, E> caerbannog();
}
+
+ /**
+ * A restricted version of {@link Current}, which does not expose the raw argument or the declared statement.
+ *
+ * @param <A> Argument type
+ * @param <D> Class representing declared version of this statement
+ */
+ @Beta
+ interface UndeclaredCurrent<A, D extends DeclaredStatement<A>> extends Current<A, D> {
+ @Deprecated
+ @Override
+ default String rawArgument() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Deprecated
+ @Override
+ default D declared() {
+ throw new UnsupportedOperationException();
+ }
+ }
}
*/
void addRequiredSource(SourceIdentifier dependency);
- // YANG example: RPC/action statements always have 'input' and 'output' defined
- @Beta
- <X, Y extends DeclaredStatement<X>, Z extends EffectiveStatement<X, Y>>
- @NonNull Mutable<X, Y, Z> addEffectiveSubstatement(StatementSupport<X, Y, Z> support, @Nullable X arg);
-
/**
* Adds an effective statement to collection of substatements.
*
* @param substatement substatement
* @throws IllegalStateException if added in declared phase
- * @throws NullPointerException if statement parameter is null
+ * @throws NullPointerException if {@code substatement} is null
*/
void addEffectiveSubstatement(Mutable<?, ?, ?> substatement);
*/
void addEffectiveSubstatements(Collection<? extends Mutable<?, ?, ?>> statements);
+ /**
+ * Adds a purely-effective statement to collection of substatements. The statement will report a {@code null}
+ * {@link EffectiveStatement#getDeclared()} object. A typical example of statements which require this mechanics
+ * are {@code rpc} and {@code action} statements, which always have {@code input} and {@code output}
+ * substatements, even if those are not declared in YANG text.
+ *
+ * @param support Statement support of the statement being created
+ * @param arg Effective argument. If specified as {@code null}, statement support will be consulted for the
+ * empty argument.
+ * @throws IllegalArgumentException if {@code support} does not implement {@link UndeclaredStatementFactory}
+ * @throws IllegalStateException if added in declared phase
+ * @throws NullPointerException if {@code support} is null
+ */
+ @Beta
+ <X, Y extends DeclaredStatement<X>, Z extends EffectiveStatement<X, Y>>
+ @NonNull Mutable<X, Y, Z> addUndeclaredSubstatement(StatementSupport<X, Y, Z> support, @Nullable X arg);
+
@Beta
void removeStatementFromEffectiveSubstatements(StatementDefinition statementDef);
--- /dev/null
+/*
+ * 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.spi.meta;
+
+import com.google.common.annotations.Beta;
+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.parser.spi.meta.EffectiveStmtCtx.Current;
+import org.opendaylight.yangtools.yang.parser.spi.meta.EffectiveStmtCtx.UndeclaredCurrent;
+
+/**
+ * An entity capable of creating undeclared {@link EffectiveStatement} instances for a particular type. Unlike
+ * {@link StatementFactory}, effective statements created through this interface are expected to return a {@code null}
+ * from {@link EffectiveStatement#getDeclared()}.
+ *
+ * @param <A> Argument type
+ * @param <D> Declared Statement representation
+ * @param <E> Effective Statement representation
+ */
+@Beta
+public interface UndeclaredStatementFactory<A, D extends DeclaredStatement<A>, E extends EffectiveStatement<A, D>> {
+ /**
+ * Create a {@link EffectiveStatement} for specified context. Implementations of this method must not access
+ * {@link Current#declared()} or {@link Current#rawArgument()}.
+ *
+ * @param stmt Effective capture of this statement's significant state
+ * @param effectiveSubstatements effectively-visible substatements
+ * @return An effective statement instance
+ */
+ @NonNull E createUndeclaredEffective(@NonNull UndeclaredCurrent<A, D> stmt,
+ @NonNull Stream<? extends StmtContext<?, ?, ?>> effectiveSubstatements);
+}