--- /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.parser.stmt.reactor;
+
+import static com.google.common.base.Preconditions.checkState;
+
+import java.util.Collection;
+import java.util.Optional;
+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.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;
+
+/**
+ * Intermediate subclass of StatementContextBase facing the parser stream via implementation of ResumedStatement. This
+ * shields inference-type substatements from these details.
+ *
+ * @param <A> Argument type
+ * @param <D> Declared Statement representation
+ * @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 StatementMap substatements = StatementMap.empty();
+
+ AbstractResumedStatement(final StatementDefinitionContext<A, D, E> def, final StatementSourceReference ref,
+ final String rawArgument) {
+ super(def, ref, rawArgument);
+ }
+
+ AbstractResumedStatement(final StatementDefinitionContext<A, D, E> def, final StatementSourceReference ref,
+ final String rawArgument, final CopyType copyType) {
+ super(def, ref, rawArgument, copyType);
+ }
+
+ AbstractResumedStatement(final StatementContextBase<A, D, E> original, final CopyType copyType) {
+ super(original, copyType);
+ }
+
+ AbstractResumedStatement(final AbstractResumedStatement<A, D, E> original) {
+ super(original);
+ this.substatements = original.substatements;
+ }
+
+ @Override
+ public Collection<? extends StmtContext<?, ?, ?>> declaredSubstatements() {
+ return substatements.values();
+ }
+
+ @Override
+ public Collection<? extends StatementContextBase<?, ?, ?>> mutableDeclaredSubstatements() {
+ return substatements.values();
+ }
+
+ @Override
+ public @NonNull StatementDefinition getDefinition() {
+ return getPublicDefinition();
+ }
+
+ @Override
+ public @NonNull StatementSourceReference getSourceReference() {
+ return getStatementSourceReference();
+ }
+
+ @Override
+ public boolean isFullyDefined() {
+ return fullyDefined();
+ }
+
+ /**
+ * Create a new substatement at the specified offset.
+ *
+ * @param offset Substatement offset
+ * @param def definition context
+ * @param ref source reference
+ * @param argument statement argument
+ * @param <X> new substatement argument type
+ * @param <Y> new substatement declared type
+ * @param <Z> new substatement effective type
+ * @return A new substatement
+ */
+ @SuppressWarnings("checkstyle:methodTypeParameterName")
+ final <X, Y extends DeclaredStatement<X>, Z extends EffectiveStatement<X, Y>>
+ AbstractResumedStatement<X, Y, Z> createSubstatement(final int offset,
+ final StatementDefinitionContext<X, Y, Z> def, final StatementSourceReference ref,
+ final String argument) {
+ final ModelProcessingPhase inProgressPhase = getRoot().getSourceContext().getInProgressPhase();
+ checkState(inProgressPhase != ModelProcessingPhase.EFFECTIVE_MODEL,
+ "Declared statement cannot be added in effective phase at: %s", getStatementSourceReference());
+
+ final Optional<StatementSupport<?, ?, ?>> implicitParent =
+ definition().getImplicitParentFor(def.getPublicView());
+ if (implicitParent.isPresent()) {
+ return createImplicitParent(offset, implicitParent.get(), ref, argument).createSubstatement(offset, def,
+ ref, argument);
+ }
+
+ final AbstractResumedStatement<X, Y, Z> ret = new SubstatementContext<>(this, def, ref, argument);
+ substatements = substatements.put(offset, ret);
+ def.onStatementAdded(ret);
+ return ret;
+ }
+
+ /**
+ * Lookup substatement by its offset in this statement.
+ *
+ * @param offset Substatement offset
+ * @return Substatement, or null if substatement does not exist.
+ */
+ final AbstractResumedStatement<?, ?, ?> lookupSubstatement(final int offset) {
+ return substatements.get(offset);
+ }
+
+ final void resizeSubstatements(final int expectedSize) {
+ substatements = substatements.ensureCapacity(expectedSize);
+ }
+
+ final void walkChildren(final ModelProcessingPhase phase) {
+ checkState(isFullyDefined());
+ substatements.values().forEach(stmt -> {
+ stmt.walkChildren(phase);
+ stmt.endDeclared(phase);
+ });
+ }
+
+ private AbstractResumedStatement<?, ?, ?> createImplicitParent(final int offset,
+ final StatementSupport<?, ?, ?> implicitParent, final StatementSourceReference ref, final String argument) {
+ final StatementDefinitionContext<?, ?, ?> def = new StatementDefinitionContext<>(implicitParent);
+ return createSubstatement(offset, def, ImplicitSubstatement.of(ref), argument);
+ }
+}
* of this class, hence recursive lookups from them cross this class.
*/
public class RootStatementContext<A, D extends DeclaredStatement<A>, E extends EffectiveStatement<A, D>> extends
- StatementContextBase<A, D, E> {
+ AbstractResumedStatement<A, D, E> {
public static final YangVersion DEFAULT_VERSION = YangVersion.VERSION_1;
protected boolean isParentSupportedByFeatures() {
return true;
}
+
+ @Override
+ StatementContextBase<A, D, E> reparent(final StatementContextBase<?, ?, ?> newParent) {
+ throw new UnsupportedOperationException("Root statement cannot be reparented to" + newParent);
+ }
}
return inProgressPhase;
}
- Optional<StatementContextBase<?, ?, ?>> lookupDeclaredChild(final StatementContextBase<?, ?, ?> current,
+ Optional<AbstractResumedStatement<?, ?, ?>> lookupDeclaredChild(final AbstractResumedStatement<?, ?, ?> current,
final int childId) {
if (current == null) {
return Optional.empty();
}
// Fast path: we are entering a statement which was emitted in previous phase
- StatementContextBase<?, ?, ?> existing = current.lookupSubstatement(childId);
+ AbstractResumedStatement<?, ?, ?> existing = current.lookupSubstatement(childId);
while (existing != null && StatementSource.CONTEXT == existing.getStatementSource()) {
existing = existing.lookupSubstatement(childId);
}
return Optional.ofNullable(existing);
}
- StatementContextBase<?, ?, ?> createDeclaredChild(final StatementContextBase<?, ?, ?> current, final int childId,
- final QName name, final String argument, final StatementSourceReference ref) {
+ AbstractResumedStatement<?, ?, ?> createDeclaredChild(final AbstractResumedStatement<?, ?, ?> current,
+ final int childId, final QName name, final String argument, final StatementSourceReference ref) {
StatementDefinitionContext<?, ?, ?> def = currentContext.getStatementDefinition(getRootVersion(), name);
if (def == null) {
def = currentContext.getModelDefinedStatementDefinition(name);
import org.opendaylight.yangtools.yang.parser.spi.source.ImplicitSubstatement;
import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
import org.opendaylight.yangtools.yang.parser.spi.source.StatementSourceReference;
-import org.opendaylight.yangtools.yang.parser.spi.source.StatementWriter.ResumedStatement;
import org.opendaylight.yangtools.yang.parser.spi.source.SupportedFeaturesNamespace;
import org.opendaylight.yangtools.yang.parser.spi.source.SupportedFeaturesNamespace.SupportedFeatures;
import org.opendaylight.yangtools.yang.parser.stmt.reactor.NamespaceBehaviourWithListeners.KeyedValueAddedListener;
* @param <E> Effective Statement representation
*/
public abstract class StatementContextBase<A, D extends DeclaredStatement<A>, E extends EffectiveStatement<A, D>>
- extends NamespaceStorageSupport implements Mutable<A, D, E>, ResumedStatement {
+ extends NamespaceStorageSupport implements Mutable<A, D, E> {
/**
* Event listener when an item is added to model namespace.
*/
private Multimap<ModelProcessingPhase, ContextMutation> phaseMutation = ImmutableMultimap.of();
private List<Mutable<?, ?, ?>> effective = ImmutableList.of();
private List<StmtContext<?, ?, ?>> effectOfStatement = ImmutableList.of();
- private StatementMap substatements = StatementMap.empty();
private @Nullable ModelProcessingPhase completedPhase;
private @Nullable D declaredInstance;
private @Nullable E effectiveInstance;
- // Common state bits
+ // Master flag controlling whether this context can yield an effective statement
+ // FIXME: investigate the mechanics that are being supported by this, as it would be beneficial if we can get rid
+ // of this flag -- eliminating the initial alignment shadow used by below gap-filler fields.
private boolean isSupportedToBuildEffective = true;
+
+ // Flag for use with AbstractResumedStatement. This is hiding in the alignment shadow created by above boolean
private boolean fullyDefined;
- // Flags for use with SubstatementContext. These are hiding in the alignment shadow created by above booleans and
+ // Flags for use with SubstatementContext. These are hiding in the alignment shadow created by above boolean and
// hence improve memory layout.
private byte flags;
this.copyHistory = original.getCopyHistory();
this.originalCtx = original.getOriginalCtx().orElse(original);
this.prevCopyCtx = original;
- this.substatements = original.substatements;
this.effective = original.effective;
}
}
@Override
- public Collection<? extends StmtContext<?, ?, ?>> declaredSubstatements() {
- return substatements.values();
- }
-
- @Override
- public Collection<? extends Mutable<?, ?, ?>> mutableDeclaredSubstatements() {
- return substatements.values();
- }
+ public abstract Collection<? extends StatementContextBase<?, ?, ?>> mutableDeclaredSubstatements();
@Override
public Collection<? extends StmtContext<?, ?, ?>> effectiveSubstatements() {
shrinkEffective();
}
+ // YANG example: RPC/action statements always have 'input' and 'output' defined
+ @Beta
+ public <X, Y extends DeclaredStatement<X>, Z extends EffectiveStatement<X, Y>> @NonNull Mutable<X, Y, Z>
+ appendImplicitSubstatement(final StatementSupport<X, Y, Z> support, final String rawArg) {
+ // 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(getStatementSourceReference()), rawArg);
+ support.onStatementAdded(ret);
+ addEffectiveSubstatement(ret);
+ return ret;
+ }
+
/**
* Adds an effective statement to collection of substatements.
*
}
}
- /**
- * Create a new substatement at the specified offset.
- *
- * @param offset Substatement offset
- * @param def definition context
- * @param ref source reference
- * @param argument statement argument
- * @param <X> new substatement argument type
- * @param <Y> new substatement declared type
- * @param <Z> new substatement effective type
- * @return A new substatement
- */
- @SuppressWarnings("checkstyle:methodTypeParameterName")
- public final <X, Y extends DeclaredStatement<X>, Z extends EffectiveStatement<X, Y>>
- StatementContextBase<X, Y, Z> createSubstatement(final int offset,
- final StatementDefinitionContext<X, Y, Z> def, final StatementSourceReference ref,
- final String argument) {
- final ModelProcessingPhase inProgressPhase = getRoot().getSourceContext().getInProgressPhase();
- checkState(inProgressPhase != ModelProcessingPhase.EFFECTIVE_MODEL,
- "Declared statement cannot be added in effective phase at: %s", getStatementSourceReference());
-
- final Optional<StatementSupport<?, ?, ?>> implicitParent = definition.getImplicitParentFor(def.getPublicView());
- if (implicitParent.isPresent()) {
- return createImplicitParent(offset, implicitParent.get(), ref, argument).createSubstatement(offset, def,
- ref, argument);
- }
-
- final StatementContextBase<X, Y, Z> ret = new SubstatementContext<>(this, def, ref, argument);
- substatements = substatements.put(offset, ret);
- def.onStatementAdded(ret);
- return ret;
- }
-
- private StatementContextBase<?, ?, ?> createImplicitParent(final int offset,
- final StatementSupport<?, ?, ?> implicitParent, final StatementSourceReference ref, final String argument) {
- final StatementDefinitionContext<?, ?, ?> def = new StatementDefinitionContext<>(implicitParent);
- return createSubstatement(offset, def, ImplicitSubstatement.of(ref), argument);
- }
-
- public void appendImplicitStatement(final StatementSupport<?, ?, ?> statementToAdd) {
- createSubstatement(substatements.capacity(), new StatementDefinitionContext<>(statementToAdd),
- ImplicitSubstatement.of(getStatementSourceReference()), null);
- }
-
- /**
- * Lookup substatement by its offset in this statement.
- *
- * @param offset Substatement offset
- * @return Substatement, or null if substatement does not exist.
- */
- final StatementContextBase<?, ?, ?> lookupSubstatement(final int offset) {
- return substatements.get(offset);
+ // Exists only due to memory optimization
+ final boolean fullyDefined() {
+ return fullyDefined;
}
+ // Exists only due to memory optimization, should live in AbstractResumedStatement
final void setFullyDefined() {
- this.fullyDefined = true;
- }
-
- final void resizeSubstatements(final int expectedSize) {
- substatements = substatements.ensureCapacity(expectedSize);
- }
-
- final void walkChildren(final ModelProcessingPhase phase) {
- checkState(fullyDefined);
- substatements.values().forEach(stmt -> {
- stmt.walkChildren(phase);
- stmt.endDeclared(phase);
- });
+ fullyDefined = true;
}
@Override
}
}
- for (final StatementContextBase<?, ?, ?> child : substatements.values()) {
+ for (final StatementContextBase<?, ?, ?> child : mutableDeclaredSubstatements()) {
finished &= child.tryToCompletePhase(phase);
}
for (final Mutable<?, ?, ?> child : effective) {
if (implicitParent.isPresent()) {
final StatementDefinitionContext<?, ?, ?> def = new StatementDefinitionContext<>(implicitParent.get());
- result = new SubstatementContext(this, def, original.getSourceReference(),
+ result = new SubstatementContext(this, def, original.getStatementSourceReference(),
original.rawStatementArgument(), original.getStatementArgument(), type);
final CopyType childCopyType;
return result;
}
- @Override
- public @NonNull StatementDefinition getDefinition() {
- return getPublicDefinition();
- }
-
- @Override
- public @NonNull StatementSourceReference getSourceReference() {
- return getStatementSourceReference();
- }
-
- @Override
- public boolean isFullyDefined() {
- return fullyDefined;
- }
-
@Beta
public final boolean hasImplicitParentSupport() {
return definition.getFactory() instanceof ImplicitParentAwareStatementSupport;
original.getStatementSourceReference(), original.rawStatementArgument(), original.getStatementArgument(),
type);
- result.addEffectiveSubstatement(new SubstatementContext<>(original, result));
+ result.addEffectiveSubstatement(original.reparent(result));
result.setCompletedPhase(original.getCompletedPhase());
return result;
}
+ abstract StatementContextBase<A, D, E> reparent(StatementContextBase<?, ?, ?> newParent);
+
/**
* Config statements are not all that common which means we are performing a recursive search towards the root
* every time {@link #isConfiguration()} is invoked. This is quite expensive because it causes a linear search
final void copyTo(final StatementContextBase<?, ?, ?> target, final CopyType typeOfCopy,
@Nullable final QNameModule targetModule) {
- final Collection<Mutable<?, ?, ?>> buffer = new ArrayList<>(substatements.size() + effective.size());
+ final Collection<? extends StatementContextBase<?, ?, ?>> declared = mutableDeclaredSubstatements();
+ final Collection<Mutable<?, ?, ?>> buffer = new ArrayList<>(declared.size() + effective.size());
- for (final Mutable<?, ?, ?> stmtContext : substatements.values()) {
+ for (final Mutable<?, ?, ?> stmtContext : declared) {
if (stmtContext.isSupportedByFeatures()) {
copySubstatement(stmtContext, target, typeOfCopy, targetModule, buffer);
}
}
-
for (final Mutable<?, ?, ?> stmtContext : effective) {
copySubstatement(stmtContext, target, typeOfCopy, targetModule, buffer);
}
import static com.google.common.base.Preconditions.checkArgument;
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;
private final ModelProcessingPhase phase;
private final SourceSpecificContext ctx;
- private StatementContextBase<?, ?, ?> current;
+ private AbstractResumedStatement<?, ?, ?> current;
StatementContextWriter(final SourceSpecificContext ctx, final ModelProcessingPhase phase) {
this.ctx = requireNonNull(ctx);
@Override
public Optional<? extends ResumedStatement> resumeStatement(final int childId) {
- final Optional<StatementContextBase<?, ?, ?>> existing = ctx.lookupDeclaredChild(current, childId);
+ final Optional<AbstractResumedStatement<?, ?, ?>> existing = ctx.lookupDeclaredChild(current, childId);
existing.ifPresent(this::resumeStatement);
return existing;
}
- private void resumeStatement(final StatementContextBase<?, ?, ?> child) {
+ private void resumeStatement(final AbstractResumedStatement<?, ?, ?> child) {
if (child.isFullyDefined()) {
child.walkChildren(phase);
child.endDeclared(phase);
@Override
public void startStatement(final int childId, final QName name, final String argument,
final StatementSourceReference ref) {
- final Optional<StatementContextBase<?, ?, ?>> existing = ctx.lookupDeclaredChild(current, childId);
+ final Optional<AbstractResumedStatement<?, ?, ?>> existing = ctx.lookupDeclaredChild(current, childId);
current = existing.isPresent() ? existing.get()
: verifyNotNull(ctx.createDeclaredChild(current, childId, name, argument, ref));
}
}
private void exitStatement() {
+ // TODO: AbstractResumedStatement should only ever have AbstractResumedStatement parents, which would:
+ // - remove the StatementSource check
+ // - allow endDeclared() to be moved to AbstractResumedStatement
+ // - remove the need for verify()
StatementContextBase<?, ?, ?> parentContext = current.getParentContext();
while (parentContext != null && StatementSource.CONTEXT == parentContext.getStatementSource()) {
parentContext.endDeclared(phase);
parentContext = parentContext.getParentContext();
}
- current = parentContext;
+ if (parentContext != null) {
+ verify(parentContext instanceof AbstractResumedStatement, "Unexpected parent context %s", parentContext);
+ current = (AbstractResumedStatement<?, ?, ?>) parentContext;
+ } else {
+ current = null;
+ }
}
}
abstract class StatementMap {
private static final class Empty extends StatementMap {
@Override
- StatementContextBase<?, ?, ?> get(final int index) {
+ AbstractResumedStatement<?, ?, ?> get(final int index) {
return null;
}
@Override
- StatementMap put(final int index, final StatementContextBase<?, ?, ?> obj) {
+ StatementMap put(final int index, final AbstractResumedStatement<?, ?, ?> obj) {
return index == 0 ? new Singleton(obj) : new Regular(index, obj);
}
@Override
- Collection<StatementContextBase<?, ?, ?>> values() {
+ Collection<AbstractResumedStatement<?, ?, ?>> values() {
return ImmutableList.of();
}
}
private static final class Regular extends StatementMap {
- private StatementContextBase<?, ?, ?>[] elements;
+ private AbstractResumedStatement<?, ?, ?>[] elements;
private int size;
Regular(final int expectedLimit) {
- elements = new StatementContextBase<?, ?, ?>[expectedLimit];
+ elements = new AbstractResumedStatement<?, ?, ?>[expectedLimit];
}
- Regular(final int index, final StatementContextBase<?, ?, ?> object) {
+ Regular(final int index, final AbstractResumedStatement<?, ?, ?> object) {
this(index + 1, index, object);
}
- Regular(final StatementContextBase<?, ?, ?> object0, final int index,
- final StatementContextBase<?, ?, ?> object) {
+ Regular(final AbstractResumedStatement<?, ?, ?> object0, final int index,
+ final AbstractResumedStatement<?, ?, ?> object) {
this(index + 1, 0, object0);
elements[index] = requireNonNull(object);
size = 2;
}
- Regular(final int expectedLimit, final int index, final StatementContextBase<?, ?, ?> object) {
+ Regular(final int expectedLimit, final int index, final AbstractResumedStatement<?, ?, ?> object) {
this(expectedLimit);
elements[index] = requireNonNull(object);
size = 1;
}
@Override
- StatementContextBase<?, ?, ?> get(final int index) {
+ AbstractResumedStatement<?, ?, ?> get(final int index) {
return index >= elements.length ? null : elements[index];
}
@Override
- StatementMap put(final int index, final StatementContextBase<?, ?, ?> obj) {
+ StatementMap put(final int index, final AbstractResumedStatement<?, ?, ?> obj) {
if (index < elements.length) {
checkArgument(elements[index] == null);
} else {
}
@Override
- Collection<StatementContextBase<?, ?, ?>> values() {
+ Collection<AbstractResumedStatement<?, ?, ?>> values() {
return new RegularAsCollection<>(elements, size);
}
}
private static final class Singleton extends StatementMap {
- private final StatementContextBase<?, ?, ?> object;
+ private final AbstractResumedStatement<?, ?, ?> object;
- Singleton(final StatementContextBase<?, ?, ?> object) {
+ Singleton(final AbstractResumedStatement<?, ?, ?> object) {
this.object = requireNonNull(object);
}
@Override
- StatementContextBase<?, ?, ?> get(final int index) {
+ AbstractResumedStatement<?, ?, ?> get(final int index) {
return index == 0 ? object : null;
}
@Override
- StatementMap put(final int index, final StatementContextBase<?, ?, ?> obj) {
+ StatementMap put(final int index, final AbstractResumedStatement<?, ?, ?> obj) {
checkArgument(index != 0);
return new Regular(this.object, index, obj);
}
@Override
- Collection<StatementContextBase<?, ?, ?>> values() {
+ Collection<AbstractResumedStatement<?, ?, ?>> values() {
return ImmutableList.of(object);
}
* @param index Element index, must be non-negative
* @return Requested element or null if there is no element at that index
*/
- abstract @Nullable StatementContextBase<?, ?, ?> get(int index);
+ abstract @Nullable AbstractResumedStatement<?, ?, ?> 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 StatementContextBase<?, ?, ?> obj);
+ abstract @NonNull StatementMap put(int index, @NonNull AbstractResumedStatement<?, ?, ?> obj);
/**
* Return a read-only view of the elements in this map. Unlike other maps, this view does not detect concurrent
*
* @return Read-only view of available statements.
*/
- abstract @NonNull Collection<StatementContextBase<?, ?, ?>> values();
+ abstract @NonNull Collection<AbstractResumedStatement<?, ?, ?>> values();
abstract int size();
import org.opendaylight.yangtools.yang.parser.spi.source.StatementSourceReference;
final class SubstatementContext<A, D extends DeclaredStatement<A>, E extends EffectiveStatement<A, D>> extends
- StatementContextBase<A, D, E> {
+ AbstractResumedStatement<A, D, E> {
private final StatementContextBase<?, ?, ?> parent;
private final A argument;
: original.definition().adaptArgumentValue(original, targetModule);
}
- SubstatementContext(final StatementContextBase<A, D, E> original, final StatementContextBase<?, ?, ?> parent) {
+ private SubstatementContext(final SubstatementContext<A, D, E> original,
+ final StatementContextBase<?, ?, ?> parent) {
super(original);
this.parent = requireNonNull(parent, "Parent must not be null");
- this.argument = original.getStatementArgument();
+ this.argument = original.argument;
}
@Override
protected boolean isParentSupportedByFeatures() {
return parent.isSupportedByFeatures();
}
+
+ @Override
+ SubstatementContext<A, D, E> reparent(final StatementContextBase<?, ?, ?> newParent) {
+ return new SubstatementContext<>(this, newParent);
+ }
}
super.onFullDefinitionDeclared(stmt);
if (StmtContextUtils.findFirstDeclaredSubstatement(stmt, InputStatement.class) == null) {
- ((StatementContextBase<?, ?, ?>) stmt).appendImplicitStatement(InputStatementRFC7950Support.getInstance());
+ ((StatementContextBase<?, ?, ?>) stmt).appendImplicitSubstatement(
+ InputStatementRFC7950Support.getInstance(), null);
}
-
if (StmtContextUtils.findFirstDeclaredSubstatement(stmt, OutputStatement.class) == null) {
- ((StatementContextBase<?, ?, ?>) stmt).appendImplicitStatement(OutputStatementRFC7950Support.getInstance());
+ ((StatementContextBase<?, ?, ?>) stmt).appendImplicitSubstatement(
+ OutputStatementRFC7950Support.getInstance(), null);
}
}
protected SubstatementValidator getSubstatementValidator() {
return SUBSTATEMENT_VALIDATOR;
}
-}
\ No newline at end of file
+}
super.onFullDefinitionDeclared(stmt);
if (StmtContextUtils.findFirstDeclaredSubstatement(stmt, InputStatement.class) == null) {
- ((StatementContextBase<?, ?, ?>) stmt).appendImplicitStatement(implictInput());
+ ((StatementContextBase<?, ?, ?>) stmt).appendImplicitSubstatement(implictInput(), null);
}
-
if (StmtContextUtils.findFirstDeclaredSubstatement(stmt, OutputStatement.class) == null) {
- ((StatementContextBase<?, ?, ?>) stmt).appendImplicitStatement(implictOutput());
+ ((StatementContextBase<?, ?, ?>) stmt).appendImplicitSubstatement(implictOutput(), null);
}
}