This caching field is useful, except it is clear that only the
original instance really needs it, as InferredStatementContext
will just walk through prototype to acquire it from there.
Move the field into AbstractResumedStatement, i.e.
originally-declared statements, taking buildDeclared() method
implementation there.
This reduces the size of StatementContextBase by one reference
field, which helps InferredStatementContext, as it can now hold
pointer to the original context without increasing object size.
Having the original context allows us to more efficiently shortcut
to the original definition -- which is useful for other methods
as well.
JIRA: YANGTOOLS-784
Change-Id: Ib8767a892b8c8aaa0e3f7da10ac794167269fff6
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
(cherry picked from commit
4159f31b29b342181a5e19b3732b36954592a8a8)
(cherry picked from commit
309569041fb3a539ea7683729e357197956f0d8a)
import java.util.Collection;
import java.util.Optional;
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;
private final String rawArgument;
private StatementMap substatements = StatementMap.empty();
+ private @Nullable D declaredInstance;
// Copy constructor
AbstractResumedStatement(final AbstractResumedStatement<A, D, E> 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,
return substatements.values();
}
+ @Override
+ public final D buildDeclared() {
+ final D existing = declaredInstance;
+ if (existing != null) {
+ return existing;
+ }
+ final ModelProcessingPhase phase = getCompletedPhase();
+ checkState(phase == ModelProcessingPhase.FULL_DECLARATION || phase == ModelProcessingPhase.EFFECTIVE_MODEL,
+ "Cannot build declared instance after phase %s", phase);
+ return declaredInstance = definition().getFactory().createDeclared(this);
+ }
+
@Override
public @NonNull StatementDefinition getDefinition() {
return getPublicDefinition();
private final @NonNull StatementContextBase<A, D, E> prototype;
private final @NonNull StatementContextBase<?, ?, ?> parent;
+ private final @NonNull StmtContext<A, D, E> originalCtx;
private final @NonNull CopyType childCopyType;
private final QNameModule targetModule;
private final A argument;
this.childCopyType = original.childCopyType;
this.targetModule = original.targetModule;
this.prototype = original.prototype;
+ this.originalCtx = original.originalCtx;
this.argument = original.argument;
}
: prototype.definition().adaptArgumentValue(prototype, targetModule);
this.childCopyType = requireNonNull(childCopyType);
this.targetModule = targetModule;
+ // FIXME: 5.0.0: ugly cast due getOriginalCtx() return type :(
+ this.originalCtx = (StmtContext<A, D, E>) prototype.getOriginalCtx().orElse(prototype);
// FIXME: YANGTOOLS-784: instantiate these lazily
addEffectiveSubstatements(createEffective());
@Override
public StatementSourceReference getStatementSourceReference() {
- return prototype.getStatementSourceReference();
+ return originalCtx.getStatementSourceReference();
}
@Override
public String rawStatementArgument() {
- return prototype.rawStatementArgument();
+ return originalCtx.rawStatementArgument();
}
@Override
public Optional<StmtContext<?, ?, ?>> getOriginalCtx() {
- final Optional<StmtContext<?, ?, ?>> orig = prototype.getOriginalCtx();
- return orig.isPresent() ? orig : Optional.of(prototype);
+ return Optional.of(originalCtx);
}
@Override
}
@Override
- D createDeclared() {
- return prototype.buildDeclared();
+ public D buildDeclared() {
+ /*
+ * Share original instance of declared statement between all effective statements which have been copied or
+ * derived from this original declared statement.
+ */
+ return originalCtx.buildDeclared();
}
@Override
private List<StmtContext<?, ?, ?>> effectOfStatement = ImmutableList.of();
private @Nullable ModelProcessingPhase completedPhase;
- private @Nullable D declaredInstance;
private @Nullable E effectiveInstance;
// Master flag controlling whether this context can yield an effective statement
this.isSupportedToBuildEffective = original.isSupportedToBuildEffective;
this.fullyDefined = original.fullyDefined;
this.completedPhase = original.completedPhase;
- this.declaredInstance = original.declaredInstance;
this.flags = original.flags;
}
fullyDefined = true;
}
- @Override
- public D buildDeclared() {
- final D existing = declaredInstance;
- if (existing != null) {
- return existing;
- }
- checkArgument(completedPhase == ModelProcessingPhase.FULL_DECLARATION
- || completedPhase == ModelProcessingPhase.EFFECTIVE_MODEL);
- return declaredInstance = createDeclared();
- }
-
- @NonNull D createDeclared() {
- return definition.getFactory().createDeclared(this);
- }
-
@Override
public E buildEffective() {
final E existing = effectiveInstance;
*
* @return Original definition, if this statement was copied.
*/
+ // FIXME: 5.0.0: this should return Optional<? extends StmtContext<A, D, E>>, is that feasible?
Optional<StmtContext<?, ?, ?>> getOriginalCtx();
/**
*
* @return Context of the previous copy of this statement, if this statement has been copied.
*/
+ // FIXME: 5.0.0: this should return Optional<? extends StmtContext<A, D, E>>
Optional<? extends StmtContext<?, ?, ?>> getPreviousCopyCtx();
ModelProcessingPhase getCompletedPhase();