From 7bda1a105c1f4d3f7caeabdb84e48fa75986d8f9 Mon Sep 17 00:00:00 2001 From: Robert Varga Date: Tue, 30 Nov 2021 22:52:39 +0100 Subject: [PATCH] Decouple choice/case statements Use StatementSupportNamespace to perform on-demand lookup of CaseStatementSupport instead of hard-wiring it at instantiation time. JIRA: YANGTOOLS-1371 Change-Id: Id6d2b8185918c206659447b58341edfb4860f349 Signed-off-by: Robert Varga --- .../reactor/AbstractResumedStatement.java | 7 ++--- .../stmt/reactor/StatementContextBase.java | 8 ++--- .../reactor/StatementDefinitionContext.java | 7 +++-- .../rfc7950/reactor/RFC7950Reactors.java | 11 +++---- .../stmt/meta/ChoiceStatementSupport.java | 29 ++++++++++--------- .../ImplicitParentAwareStatementSupport.java | 6 ++-- 6 files changed, 32 insertions(+), 36 deletions(-) diff --git a/parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/AbstractResumedStatement.java b/parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/AbstractResumedStatement.java index c73b585592..89df4c0852 100644 --- a/parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/AbstractResumedStatement.java +++ b/parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/AbstractResumedStatement.java @@ -172,11 +172,10 @@ abstract class AbstractResumedStatement, E ext checkState(inProgressPhase != ModelProcessingPhase.EFFECTIVE_MODEL, "Declared statement cannot be added in effective phase at: %s", sourceReference()); - final Optional> implicitParent = - definition().getImplicitParentFor(def.getPublicView()); + final var implicitParent = definition().getImplicitParentFor(this, def.getPublicView()); if (implicitParent.isPresent()) { - return createImplicitParent(offset, implicitParent.get(), ref, argument).createSubstatement(offset, def, - ref, argument); + return createImplicitParent(offset, implicitParent.orElseThrow(), ref, argument) + .createSubstatement(offset, def, ref, argument); } final AbstractResumedStatement ret = new SubstatementContext<>(this, def, ref, argument); diff --git a/parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/StatementContextBase.java b/parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/StatementContextBase.java index c797dacaf5..3e9405d829 100644 --- a/parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/StatementContextBase.java +++ b/parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/StatementContextBase.java @@ -819,8 +819,7 @@ public abstract class StatementContextBase, E private , Z extends EffectiveStatement> Mutable childCopyOf( final StatementContextBase original, final CopyType type, final QNameModule targetModule) { - final Optional> implicitParent = definition.getImplicitParentFor( - original.publicDefinition()); + final var implicitParent = definition.getImplicitParentFor(this, original.publicDefinition()); final StatementContextBase result; final InferredStatementContext copy; @@ -873,13 +872,12 @@ public abstract class StatementContextBase, E @Beta public final StatementContextBase wrapWithImplicit(final StatementContextBase original) { - final Optional> optImplicit = definition.getImplicitParentFor( - original.publicDefinition()); + final var optImplicit = definition.getImplicitParentFor(this, original.publicDefinition()); if (optImplicit.isEmpty()) { return original; } - final StatementDefinitionContext def = new StatementDefinitionContext<>(optImplicit.get()); + final StatementDefinitionContext def = new StatementDefinitionContext<>(optImplicit.orElseThrow()); final CopyType type = original.history().getLastOperation(); final SubstatementContext result = new SubstatementContext(original.getParentContext(), def, original.sourceReference(), original.rawArgument(), original.argument(), type); diff --git a/parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/StatementDefinitionContext.java b/parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/StatementDefinitionContext.java index 8e50390ce8..5eaa0ac809 100644 --- a/parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/StatementDefinitionContext.java +++ b/parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/StatementDefinitionContext.java @@ -22,6 +22,7 @@ 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.ImplicitParentAwareStatementSupport; import org.opendaylight.yangtools.yang.parser.spi.meta.ModelProcessingPhase; +import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceStmtCtx; import org.opendaylight.yangtools.yang.parser.spi.meta.OverrideChildStatementSupport; import org.opendaylight.yangtools.yang.parser.spi.meta.StatementFactory; import org.opendaylight.yangtools.yang.parser.spi.meta.StatementSupport; @@ -55,9 +56,11 @@ final class StatementDefinitionContext, E exte return support.getPublicView(); } - Optional> getImplicitParentFor(final StatementDefinition stmtDef) { + Optional> getImplicitParentFor(final NamespaceStmtCtx parent, + final StatementDefinition stmtDef) { return support instanceof ImplicitParentAwareStatementSupport - ? ((ImplicitParentAwareStatementSupport) support).getImplicitParentFor(stmtDef) : Optional.empty(); + ? ((ImplicitParentAwareStatementSupport) support).getImplicitParentFor(parent, stmtDef) + : Optional.empty(); } void onStatementAdded(final Mutable stmt) { diff --git a/parser/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/reactor/RFC7950Reactors.java b/parser/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/reactor/RFC7950Reactors.java index 1d13c6b669..b4f5cb3fba 100644 --- a/parser/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/reactor/RFC7950Reactors.java +++ b/parser/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/reactor/RFC7950Reactors.java @@ -375,19 +375,16 @@ public final class RFC7950Reactors { private static @NonNull StatementSupportBundle fullDeclarationBundle(final StatementSupportBundle stmtDefBundle, final XPathSupport xpathSupport, final YangParserConfiguration config) { - final CaseStatementSupport rfc6020case = CaseStatementSupport.rfc6020Instance(config); - final CaseStatementSupport rfc7950case = CaseStatementSupport.rfc7950Instance(config); - return StatementSupportBundle.derivedFrom(stmtDefBundle) .addSupport(new LeafStatementSupport(config)) .addSupport(new ConfigStatementSupport(config)) .addSupport(new DeviationStatementSupport(config)) .addVersionSpecificSupport(VERSION_1, new DeviateStatementRFC6020Support(config)) .addVersionSpecificSupport(VERSION_1_1, new DeviateStatementRFC7950Support(config)) - .addVersionSpecificSupport(VERSION_1, ChoiceStatementSupport.rfc6020Instance(config, rfc6020case)) - .addVersionSpecificSupport(VERSION_1_1, ChoiceStatementSupport.rfc7950Instance(config, rfc7950case)) - .addVersionSpecificSupport(VERSION_1, rfc6020case) - .addVersionSpecificSupport(VERSION_1_1, rfc7950case) + .addVersionSpecificSupport(VERSION_1, ChoiceStatementSupport.rfc6020Instance(config)) + .addVersionSpecificSupport(VERSION_1_1, ChoiceStatementSupport.rfc7950Instance(config)) + .addVersionSpecificSupport(VERSION_1, CaseStatementSupport.rfc6020Instance(config)) + .addVersionSpecificSupport(VERSION_1_1, CaseStatementSupport.rfc7950Instance(config)) .addSupport(new MustStatementSupport(xpathSupport, config)) .addSupport(new MandatoryStatementSupport(config)) .addSupport(new AnyxmlStatementSupport(config)) diff --git a/parser/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/meta/ChoiceStatementSupport.java b/parser/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/meta/ChoiceStatementSupport.java index 04c04b7937..0905efcb04 100644 --- a/parser/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/meta/ChoiceStatementSupport.java +++ b/parser/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/meta/ChoiceStatementSupport.java @@ -7,6 +7,7 @@ */ package org.opendaylight.yangtools.yang.parser.rfc7950.stmt.meta; +import static com.google.common.base.Verify.verifyNotNull; import static java.util.Objects.requireNonNull; import com.google.common.annotations.Beta; @@ -39,7 +40,9 @@ import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractSchemaTreeStateme import org.opendaylight.yangtools.yang.parser.spi.meta.EffectiveStmtCtx.Current; import org.opendaylight.yangtools.yang.parser.spi.meta.ImplicitParentAwareStatementSupport; import org.opendaylight.yangtools.yang.parser.spi.meta.InferenceException; +import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceStmtCtx; import org.opendaylight.yangtools.yang.parser.spi.meta.StatementSupport; +import org.opendaylight.yangtools.yang.parser.spi.meta.StatementSupportNamespace; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; import org.opendaylight.yangtools.yang.parser.spi.meta.SubstatementValidator; import org.opendaylight.yangtools.yang.parser.spi.source.SourceException; @@ -83,28 +86,26 @@ public final class ChoiceStatementSupport .addOptional(YangStmtMapping.WHEN) .build(); - private final CaseStatementSupport implicitCase; - - private ChoiceStatementSupport(final YangParserConfiguration config, final SubstatementValidator validator, - final CaseStatementSupport implicitCase) { + private ChoiceStatementSupport(final YangParserConfiguration config, final SubstatementValidator validator) { super(YangStmtMapping.CHOICE, instantiatedPolicy(), config, requireNonNull(validator)); - this.implicitCase = requireNonNull(implicitCase); } - public static @NonNull ChoiceStatementSupport rfc6020Instance(final YangParserConfiguration config, - final CaseStatementSupport implicitCase) { - return new ChoiceStatementSupport(config, RFC6020_VALIDATOR, implicitCase); + public static @NonNull ChoiceStatementSupport rfc6020Instance(final YangParserConfiguration config) { + return new ChoiceStatementSupport(config, RFC6020_VALIDATOR); } - public static @NonNull ChoiceStatementSupport rfc7950Instance(final YangParserConfiguration config, - final CaseStatementSupport implicitCase) { - return new ChoiceStatementSupport(config, RFC7950_VALIDATOR, implicitCase); + public static @NonNull ChoiceStatementSupport rfc7950Instance(final YangParserConfiguration config) { + return new ChoiceStatementSupport(config, RFC7950_VALIDATOR); } @Override - public Optional> getImplicitParentFor(final StatementDefinition stmtDef) { - return YangValidationBundles.SUPPORTED_CASE_SHORTHANDS.contains(stmtDef) ? Optional.of(implicitCase) - : Optional.empty(); + public Optional> getImplicitParentFor(final NamespaceStmtCtx parent, + final StatementDefinition stmtDef) { + if (!YangValidationBundles.SUPPORTED_CASE_SHORTHANDS.contains(stmtDef)) { + return Optional.empty(); + } + return Optional.of(verifyNotNull(parent.getFromNamespace(StatementSupportNamespace.class, + YangStmtMapping.CASE.getStatementName()))); } @Override diff --git a/parser/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/ImplicitParentAwareStatementSupport.java b/parser/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/ImplicitParentAwareStatementSupport.java index 73e0952cfa..b6f5b3341d 100644 --- a/parser/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/ImplicitParentAwareStatementSupport.java +++ b/parser/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/ImplicitParentAwareStatementSupport.java @@ -15,8 +15,6 @@ import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition; * {@link StatementSupport} trait for statements which create intermediate parent node for some of its child nodes. * An example of this is RFC6020/RFC7950 choice statement, which creates implicit case statements for child containers * and others. - * - * @author Robert Varga */ @Beta public interface ImplicitParentAwareStatementSupport { @@ -25,9 +23,9 @@ public interface ImplicitParentAwareStatementSupport { * implementations of this interface add implicit parent to the build context hierarchy before a substatement * is created. * + * @param parent parent statement context * @param stmtDef statement definition of substatement * @return optional of implicit parent statement support */ - // FIXME: YANGTOOLS-1371: pass a NamespaceStmtCtx here, so choice/case can be decoupled - Optional> getImplicitParentFor(StatementDefinition stmtDef); + Optional> getImplicitParentFor(NamespaceStmtCtx parent, StatementDefinition stmtDef); } -- 2.36.6