X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=yang%2Fyang-parser-reactor%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fyangtools%2Fyang%2Fparser%2Fstmt%2Freactor%2FInferredStatementContext.java;h=ffc510290f93baaf8023465b56f847047f781e1d;hb=35536f9802bc1ae6fdf7435cbfed0cee58b47c68;hp=fafcd61bba6f4eaaacb2c67bf02d8743c1432743;hpb=9a725c73a1b8617bec07571ad46d3ddd155895a2;p=yangtools.git diff --git a/yang/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/InferredStatementContext.java b/yang/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/InferredStatementContext.java index fafcd61bba..ffc510290f 100644 --- a/yang/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/InferredStatementContext.java +++ b/yang/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/InferredStatementContext.java @@ -52,6 +52,9 @@ final class InferredStatementContext, E extend extends StatementContextBase implements OnDemandSchemaTreeStorageNode { private static final Logger LOG = LoggerFactory.getLogger(InferredStatementContext.class); + // Sentinel object for 'substatements' + private static final Object SWEPT_SUBSTATEMENTS = new Object(); + private final @NonNull StatementContextBase prototype; private final @NonNull StatementContextBase parent; private final @NonNull StmtContext originalCtx; @@ -60,11 +63,12 @@ final class InferredStatementContext, E extend private final A argument; /** - * Effective substatements, lazily materialized. This field can have three states: + * Effective substatements, lazily materialized. This field can have four states: *
    *
  • it can be {@code null}, in which case no materialization has taken place
  • *
  • it can be a {@link HashMap}, in which case partial materialization has taken place
  • *
  • it can be a {@link List}, in which case full materialization has taken place
  • + *
  • it can be {@link SWEPT_SUBSTATEMENTS}, in which case materialized state is no longer available
  • *
*/ private Object substatements; @@ -84,14 +88,17 @@ final class InferredStatementContext, E extend InferredStatementContext(final StatementContextBase parent, final StatementContextBase prototype, final CopyType myCopyType, final CopyType childCopyType, final QNameModule targetModule) { - super(prototype.definition(), CopyHistory.of(myCopyType, prototype.getCopyHistory())); + super(prototype.definition(), CopyHistory.of(myCopyType, prototype.history())); this.parent = requireNonNull(parent); this.prototype = requireNonNull(prototype); - this.argument = targetModule == null ? prototype.getStatementArgument() + this.argument = targetModule == null ? prototype.argument() : prototype.definition().adaptArgumentValue(prototype, targetModule); this.childCopyType = requireNonNull(childCopyType); this.targetModule = targetModule; this.originalCtx = prototype.getOriginalCtx().orElse(prototype); + + // Mark prototype as blocking statement cleanup + prototype.incRef(); } @Override @@ -226,7 +233,7 @@ final class InferredStatementContext, E extend } else { template = prototype.allSubstatementsStream() .filter(stmt -> stmt.producesEffective(SchemaTreeEffectiveStatement.class) - && templateQName.equals(stmt.getStatementArgument())) + && templateQName.equals(stmt.argument())) .findAny() .orElse(null); } @@ -240,7 +247,7 @@ final class InferredStatementContext, E extend @SuppressWarnings("unchecked") final Mutable ret = (Mutable) copySubstatement((Mutable) template) - .orElseThrow(() -> new InferenceException(getStatementSourceReference(), + .orElseThrow(() -> new InferenceException(sourceReference(), "Failed to materialize child %s template %s", qname, template)); ensureCompletedPhase(ret); addMaterialized(template, ret); @@ -252,6 +259,7 @@ final class InferredStatementContext, E extend // Instantiate this statement's effective substatements. Note this method has side-effects in namespaces and overall // BuildGlobalContext, hence it must be called at most once. private List> ensureEffectiveSubstatements() { + accessSubstatements(); return substatements instanceof List ? castEffective(substatements) : initializeSubstatements(castMaterialized(substatements)); } @@ -262,7 +270,9 @@ final class InferredStatementContext, E extend // from prototype (which is already at ModelProcessingPhase.EFFECTIVE_MODEL). if (substatements == null) { return ImmutableList.of(); - } else if (substatements instanceof HashMap) { + } + accessSubstatements(); + if (substatements instanceof HashMap) { return castMaterialized(substatements).values(); } else { return castEffective(substatements); @@ -276,16 +286,33 @@ final class InferredStatementContext, E extend @Override Stream> streamEffective() { - // FIXME: YANGTOOLS-1184: do not force initialization + accessSubstatements(); return ensureEffectiveSubstatements().stream(); } + private void accessSubstatements() { + verify(substatements != SWEPT_SUBSTATEMENTS, "Attempted to access substatements of %s", this); + } + + @Override + int sweepSubstatements() { + final Object local = substatements; + substatements = SWEPT_SUBSTATEMENTS; + int count = 0; + if (local != null) { + final List> list = castEffective(local); + sweep(list); + count = countUnswept(list); + } + return count; + } + private List> initializeSubstatements( final Map, StatementContextBase> materializedSchemaTree) { final Collection> declared = prototype.mutableDeclaredSubstatements(); final Collection> effective = prototype.mutableEffectiveSubstatements(); - final List> buffer = new ArrayList<>(declared.size() + effective.size()); + final List> buffer = new ArrayList<>(declared.size() + effective.size()); for (final Mutable stmtContext : declared) { if (stmtContext.isSupportedByFeatures()) { copySubstatement(stmtContext, buffer, materializedSchemaTree); @@ -299,6 +326,8 @@ final class InferredStatementContext, E extend buffer.size()); ret.addAll((Collection) buffer); substatements = ret; + + prototype.decRef(); return ret; } @@ -315,12 +344,12 @@ final class InferredStatementContext, E extend private void copySubstatement(final Mutable substatement, final Collection> buffer, final Map, StatementContextBase> materializedSchemaTree) { - final StatementDefinition def = substatement.getPublicDefinition(); + final StatementDefinition def = substatement.publicDefinition(); // FIXME: YANGTOOLS-652: formerly known as "isReusedByUses" if (REUSED_DEF_SET.contains(def)) { - LOG.debug("Reusing substatement {} for {}", substatement, this); - buffer.add(substatement); + LOG.trace("Reusing substatement {} for {}", substatement, this); + buffer.add(substatement.replicaAsChildOf(this)); return; } @@ -362,7 +391,7 @@ final class InferredStatementContext, E extend (StatementContextBase) copy); if (existing != null) { throw new VerifyException( - "Unexpected duplicate request for " + copy.getStatementArgument() + " previous result was " + existing); + "Unexpected duplicate request for " + copy.argument() + " previous result was " + existing); } }