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=472e407cbd92d6a37c3bb98bb2e176209fd74120;hb=41ed305a7dce99e21a7b1066711347147dc067d8;hp=3378efde40672533c8d141c404202f355a72448a;hpb=af62dc4257be32f92c6e8506fa8dabfe8a9976cd;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 3378efde40..472e407cbd 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 @@ -17,17 +17,20 @@ import java.util.List; import java.util.Optional; import java.util.stream.Stream; 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.model.api.SchemaPath; import org.opendaylight.yangtools.yang.model.api.YangStmtMapping; 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.stmt.SchemaTreeEffectiveStatement; import org.opendaylight.yangtools.yang.parser.spi.meta.CopyHistory; import org.opendaylight.yangtools.yang.parser.spi.meta.CopyType; -import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.NamespaceStorageNode; +import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.OnDemandSchemaTreeStorageNode; import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.StorageNodeType; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextDefaults; import org.opendaylight.yangtools.yang.parser.spi.source.StatementSourceReference; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -38,11 +41,12 @@ import org.slf4j.LoggerFactory; * effective substatements, which are either transformed from that prototype or added by inference. */ final class InferredStatementContext, E extends EffectiveStatement> - extends StatementContextBase { + extends StatementContextBase implements OnDemandSchemaTreeStorageNode { private static final Logger LOG = LoggerFactory.getLogger(InferredStatementContext.class); private final @NonNull StatementContextBase prototype; private final @NonNull StatementContextBase parent; + private final @NonNull StmtContext originalCtx; private final @NonNull CopyType childCopyType; private final QNameModule targetModule; private final A argument; @@ -54,7 +58,9 @@ final class InferredStatementContext, E extend this.childCopyType = original.childCopyType; this.targetModule = original.targetModule; this.prototype = original.prototype; + this.originalCtx = original.originalCtx; this.argument = original.argument; + setSubstatementsInitialized(); } InferredStatementContext(final StatementContextBase parent, final StatementContextBase prototype, @@ -66,9 +72,9 @@ final class InferredStatementContext, E extend : prototype.definition().adaptArgumentValue(prototype, targetModule); this.childCopyType = requireNonNull(childCopyType); this.targetModule = targetModule; + this.originalCtx = prototype.getOriginalCtx().orElse(prototype); - // FIXME: YANGTOOLS-784: instantiate these lazily - addEffectiveSubstatements(createEffective()); + // Note: substatements from prototype are initialized lazily through ensureSubstatements() } @Override @@ -90,28 +96,31 @@ final class InferredStatementContext, E extend @Override public StatementSourceReference getStatementSourceReference() { - return prototype.getStatementSourceReference(); + return originalCtx.getStatementSourceReference(); } @Override public String rawStatementArgument() { - return prototype.rawStatementArgument(); + return originalCtx.rawStatementArgument(); } @Override - public Optional> getOriginalCtx() { - final Optional> orig = prototype.getOriginalCtx(); - return orig.isPresent() ? orig : Optional.of(prototype); + public Optional> getOriginalCtx() { + return Optional.of(originalCtx); } @Override - public Optional> getPreviousCopyCtx() { + public Optional> getPreviousCopyCtx() { return Optional.of(prototype); } @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 @@ -119,9 +128,71 @@ final class InferredStatementContext, E extend return new InferredStatementContext<>(this, newParent); } + @Override + boolean hasEmptySubstatements() { + ensureEffectiveSubstatements(); + return hasEmptyEffectiveSubstatements(); + } + + @Override + public > @NonNull Optional findSubstatementArgument( + final @NonNull Class type) { + if (substatementsInitialized()) { + return StmtContextDefaults.findSubstatementArgument(this, type); + } + + final Optional templateArg = prototype.findSubstatementArgument(type); + if (templateArg.isEmpty()) { + return templateArg; + } + if (SchemaTreeEffectiveStatement.class.isAssignableFrom(type)) { + // X is known to be QName + return (Optional) templateArg.map(template -> ((QName) template).bindTo(targetModule)); + } + return templateArg; + } + + @Override + public boolean hasSubstatement(final @NonNull Class> type) { + return substatementsInitialized() ? StmtContextDefaults.hasSubstatement(prototype, type) + : prototype.hasSubstatement(type); + } + + @Override + public , E extends EffectiveStatement> + StmtContext requestSchemaTreeChild(final QName qname) { + LOG.debug("Materializing on lookup of {}", qname); + // FIXME: YANGTOOLS-1160: we do not want to force full materialization here + ensureEffectiveSubstatements(); + + // Now we have to do a lookup as we do not have access to the namespace being populated (yet). Here we are + // bypassing additional checks and talk directly to superclass to get the statements. + for (StmtContext stmt : super.mutableEffectiveSubstatements()) { + if (stmt.producesEffective(SchemaTreeEffectiveStatement.class) + && qname.equals(stmt.coerceStatementArgument())) { + return (StmtContext) stmt; + } + } + return null; + } + // 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> createEffective() { + @Override + void ensureEffectiveSubstatements() { + if (!substatementsInitialized()) { + initializeSubstatements(); + } + } + + @Override + Iterable> effectiveChildrenToComplete() { + // When we have not initialized, there are no statements to catch up: we will catch up when we are copying + // from prototype (which is already at ModelProcessingPhase.EFFECTIVE_MODEL) + return substatementsInitialized() ? super.effectiveChildrenToComplete() : List.of(); + } + + private void initializeSubstatements() { final Collection> declared = prototype.mutableDeclaredSubstatements(); final Collection> effective = prototype.mutableEffectiveSubstatements(); final List> buffer = new ArrayList<>(declared.size() + effective.size()); @@ -135,7 +206,9 @@ final class InferredStatementContext, E extend copySubstatement(stmtContext, buffer); } - return buffer; + // We are bypassing usual safeties here, as this is not introducing new statements but rather just materializing + // them when the need has arised. + addInitialEffectiveSubstatements(buffer); } // Statement copy mess starts here @@ -143,15 +216,11 @@ final class InferredStatementContext, E extend // FIXME: This is messy and is probably wrong in some corner case. Even if it is correct, the way how it is correct // relies on hard-coded maps. At the end of the day, the logic needs to be controlled by statement's // StatementSupport. - // FIXME: YANGTOOLS-652: these maps look very much like those in UsesStatementImpl + // FIXME: YANGTOOLS-652: this map looks very much like UsesStatementSupport.TOP_REUSED_DEF_SET private static final ImmutableSet REUSED_DEF_SET = ImmutableSet.of( YangStmtMapping.TYPE, YangStmtMapping.TYPEDEF, YangStmtMapping.USES); - private static final ImmutableSet NOCOPY_FROM_GROUPING_SET = ImmutableSet.of( - YangStmtMapping.DESCRIPTION, - YangStmtMapping.REFERENCE, - YangStmtMapping.STATUS); private void copySubstatement(final Mutable substatement, final Collection> buffer) { final StatementDefinition def = substatement.getPublicDefinition(); @@ -162,22 +231,8 @@ final class InferredStatementContext, E extend buffer.add(substatement); return; } - // FIXME: YANGTOOLS-652: formerly known as "needToCopyByUses" (note inverted check, though) - if (NOCOPY_FROM_GROUPING_SET.contains(def)) { - // This is to say: if parent of source context is a grouping, ignore this statement. - if (YangStmtMapping.GROUPING.equals(substatement.coerceParentContext().getPublicDefinition())) { - LOG.debug("Skipping grouping statement {}", substatement); - return; - } - } - // FIXME: YANGTOOLS-694: we are forcing a copy here, hence even statements not affected by parent, copyType - // or targetModule (and don't forget its substatements!). This really should be a callout - // to StatementSupport. Note if that callout is allowed to return an Optional, it can - // take care at least of the 'grouping from uses' case above. - final Mutable copy = childCopyOf(substatement, childCopyType, targetModule); - LOG.debug("Copying substatement {} for {} as {}", substatement, this, copy); - buffer.add(copy); + substatement.copyAsChildOf(this, childCopyType, targetModule).ifPresent(buffer::add); } // Statement copy mess ends here @@ -189,6 +244,7 @@ final class InferredStatementContext, E extend * properly updated there. */ @Override + @Deprecated public Optional getSchemaPath() { return substatementGetSchemaPath(); } @@ -209,7 +265,7 @@ final class InferredStatementContext, E extend } @Override - public NamespaceStorageNode getParentNamespaceStorage() { + public StatementContextBase getParentNamespaceStorage() { return parent; }