private static final Logger LOG = LoggerFactory.getLogger(StatementContextBase.class);
- //
- // {@link CopyHistory} encoded as a single byte. We still have 4 bits unused.
- //
+ // Bottom 4 bits, encoding a CopyHistory, aight?
+ private static final byte COPY_ORIGINAL = 0x00;
private static final byte COPY_LAST_TYPE_MASK = 0x03;
+ @Deprecated(since = "7.0.9")
private static final byte COPY_ADDED_BY_USES = 0x04;
private static final byte COPY_ADDED_BY_AUGMENTATION = 0x08;
- private static final byte COPY_ORIGINAL = 0x00;
- private final byte copyHistory;
+ // Top four bits, of which we define the topmost two to 0. We use the bottom two to encode last CopyType, aight?
+ private static final int COPY_CHILD_TYPE_SHIFT = 4;
+
+ private static final CopyType @NonNull [] COPY_TYPE_VALUES = CopyType.values();
static {
- final int copyTypes = CopyType.values().length;
+ final int copyTypes = COPY_TYPE_VALUES.length;
// This implies CopyType.ordinal() is <= COPY_TYPE_MASK
verify(copyTypes == COPY_LAST_TYPE_MASK + 1, "Unexpected %s CopyType values", copyTypes);
}
+ /**
+ * 8 bits worth of instance storage. This is treated as a constant bit field with following structure:
+ * <pre>
+ * <code>
+ * |7|6|5|4|3|2|1|0|
+ * |0 0|cct|a|u|lst|
+ * </code>
+ * </pre>
+ *
+ * <p>
+ * The four allocated fields are:
+ * <ul>
+ * <li>{@code lst}, encoding the four states corresponding to {@link CopyHistory#getLastOperation()}</li>
+ * <li>{@code u}, encoding {@link #isAddedByUses()}</li>
+ * <li>{@code a}, encoding {@link #isAugmenting()}</li>
+ * <li>{@code cct} encoding {@link #childCopyType()}</li>
+ * </ul>
+ * We still have two unused bits.
+ */
+ private final byte bitsAight;
+
// Note: this field can strictly be derived in InferredStatementContext, but it forms the basis of many of our
// operations, hence we want to keep it close by.
private final @NonNull StatementDefinitionContext<A, D, E> definition;
// Copy constructor used by subclasses to implement reparent()
StatementContextBase(final StatementContextBase<A, D, E> original) {
super(original);
- this.copyHistory = original.copyHistory;
+ this.bitsAight = original.bitsAight;
this.definition = original.definition;
this.executionOrder = original.executionOrder;
}
StatementContextBase(final StatementDefinitionContext<A, D, E> def) {
this.definition = requireNonNull(def);
- this.copyHistory = COPY_ORIGINAL;
+ this.bitsAight = COPY_ORIGINAL;
}
StatementContextBase(final StatementDefinitionContext<A, D, E> def, final CopyType copyType) {
this.definition = requireNonNull(def);
- this.copyHistory = (byte) copyFlags(copyType);
+ this.bitsAight = (byte) copyFlags(copyType);
}
- StatementContextBase(final StatementContextBase<A, D, E> prototype, final CopyType copyType) {
+ StatementContextBase(final StatementContextBase<A, D, E> prototype, final CopyType copyType,
+ final CopyType childCopyType) {
this.definition = prototype.definition;
- this.copyHistory = (byte) (copyFlags(copyType) | prototype.copyHistory & ~COPY_LAST_TYPE_MASK);
+ this.bitsAight = (byte) (copyFlags(copyType)
+ | prototype.bitsAight & ~COPY_LAST_TYPE_MASK | childCopyType.ordinal() << COPY_CHILD_TYPE_SHIFT);
}
private static int copyFlags(final CopyType copyType) {
}
@Override
+ @Deprecated(since = "7.0.9")
public final boolean isAddedByUses() {
- return (copyHistory & COPY_ADDED_BY_USES) != 0;
+ return (bitsAight & COPY_ADDED_BY_USES) != 0;
}
@Override
public final boolean isAugmenting() {
- return (copyHistory & COPY_ADDED_BY_AUGMENTATION) != 0;
+ return (bitsAight & COPY_ADDED_BY_AUGMENTATION) != 0;
}
@Override
public final CopyType getLastOperation() {
- return CopyType.values()[copyHistory & COPY_LAST_TYPE_MASK];
+ return COPY_TYPE_VALUES[bitsAight & COPY_LAST_TYPE_MASK];
+ }
+
+ // This method exists only for space optimization of InferredStatementContext
+ final CopyType childCopyType() {
+ return COPY_TYPE_VALUES[bitsAight >> COPY_CHILD_TYPE_SHIFT & COPY_LAST_TYPE_MASK];
}
//
final List<ReactorStmtCtx<?, ?, ?>> addEffectiveSubstatement(final List<ReactorStmtCtx<?, ?, ?>> effective,
final Mutable<?, ?, ?> substatement) {
- verifyStatement(substatement);
-
+ final ReactorStmtCtx<?, ?, ?> stmt = verifyStatement(substatement);
final List<ReactorStmtCtx<?, ?, ?>> resized = beforeAddEffectiveStatement(effective, 1);
- final ReactorStmtCtx<?, ?, ?> stmt = (ReactorStmtCtx<?, ?, ?>) substatement;
ensureCompletedExecution(stmt);
resized.add(stmt);
return resized;
abstract Iterable<ReactorStmtCtx<?, ?, ?>> effectiveChildrenToComplete();
// exposed for InferredStatementContext only
- final void ensureCompletedPhase(final Mutable<?, ?, ?> stmt) {
- verifyStatement(stmt);
- ensureCompletedExecution((ReactorStmtCtx<?, ?, ?>) stmt);
+ final ReactorStmtCtx<?, ?, ?> ensureCompletedPhase(final Mutable<?, ?, ?> stmt) {
+ final var ret = verifyStatement(stmt);
+ ensureCompletedExecution(ret);
+ return ret;
}
// Make sure target statement has transitioned at least to our phase (if we have one). This method is just before we
verify(stmt.tryToCompletePhase(executionOrder), "Statement %s cannot complete phase %s", stmt, executionOrder);
}
- private static void verifyStatement(final Mutable<?, ?, ?> stmt) {
+ private static ReactorStmtCtx<?, ?, ?> verifyStatement(final Mutable<?, ?, ?> stmt) {
verify(stmt instanceof ReactorStmtCtx, "Unexpected statement %s", stmt);
+ return (ReactorStmtCtx<?, ?, ?>) stmt;
}
private List<ReactorStmtCtx<?, ?, ?>> beforeAddEffectiveStatement(final List<ReactorStmtCtx<?, ?, ?>> effective,
@Override
final boolean doTryToCompletePhase(final byte targetOrder) {
- final boolean finished = phaseMutation.isEmpty() ? true : runMutations(targetOrder);
+ final boolean finished = phaseMutation.isEmpty() || runMutations(targetOrder);
if (completeChildren(targetOrder) && finished) {
onPhaseCompleted(targetOrder);
return true;
private boolean runMutations(final byte targetOrder) {
final ModelProcessingPhase phase = verifyNotNull(ModelProcessingPhase.ofExecutionOrder(targetOrder));
final Collection<ContextMutation> openMutations = phaseMutation.get(phase);
- return openMutations.isEmpty() ? true : runMutations(phase, openMutations);
+ return openMutations.isEmpty() || runMutations(phase, openMutations);
}
private boolean runMutations(final ModelProcessingPhase phase, final Collection<ContextMutation> openMutations) {
return null;
}
- parent.ensureCompletedPhase(copy);
+ parent.ensureCompletedExecution(copy);
return canReuseCurrent(copy) ? this : copy;
}
public final Mutable<?, ?, ?> childCopyOf(final StmtContext<?, ?, ?> stmt, final CopyType type,
final QNameModule targetModule) {
checkEffectiveModelCompleted(stmt);
- checkArgument(stmt instanceof StatementContextBase, "Unsupported statement %s", stmt);
- return childCopyOf((StatementContextBase<?, ?, ?>) stmt, type, targetModule);
+ if (stmt instanceof StatementContextBase) {
+ return childCopyOf((StatementContextBase<?, ?, ?>) stmt, type, targetModule);
+ } else if (stmt instanceof ReplicaStatementContext) {
+ return ((ReplicaStatementContext<?, ?, ?>) stmt).replicaAsChildOf(this);
+ } else {
+ throw new IllegalArgumentException("Unsupported statement " + stmt);
+ }
}
private <X, Y extends DeclaredStatement<X>, Z extends EffectiveStatement<X, Y>> Mutable<X, Y, Z> childCopyOf(
copy = new InferredStatementContext<>(result, original, childCopyType, type, targetModule);
result.addEffectiveSubstatement(copy);
+ result.definition.onStatementAdded(result);
} else {
result = copy = new InferredStatementContext<>(this, original, type, type, targetModule);
}