From 4c55bcfdbca157ccbec16d458ee860aabe1227bf Mon Sep 17 00:00:00 2001 From: Robert Varga Date: Mon, 19 Apr 2021 19:03:19 +0200 Subject: [PATCH] Cleanup unrecognized statement wrapping reactor/rfc7950 interaction around inner statements is a bit hacky in that we end up performing two unrelated semantic checks before dispatching. As it turns out, though, this only a special case of a more widely applicable pattern, where the parent statement chooses to wrap its children in a different semantic support. Separating this out makes the intent clear, as it ends up being an extension trait to StatementSupport on the side of yang-parser-reactor and has a well-understood anchor in UnrecognizedStatementSupport. Change-Id: I3b64f58239e22affccc02921efd8cd70b411d7c1 Signed-off-by: Robert Varga --- .../stmt/reactor/SourceSpecificContext.java | 12 ++------ .../reactor/StatementDefinitionContext.java | 27 ++++++++++------- .../UnrecognizedStatementSupport.java | 18 +++++++----- .../meta/OverrideChildStatementSupport.java | 29 +++++++++++++++++++ .../parser/spi/meta/StatementSupport.java | 12 -------- 5 files changed, 59 insertions(+), 39 deletions(-) create mode 100644 yang/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/OverrideChildStatementSupport.java diff --git a/yang/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/SourceSpecificContext.java b/yang/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/SourceSpecificContext.java index c32bab41ab..79d8e3af54 100644 --- a/yang/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/SourceSpecificContext.java +++ b/yang/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/SourceSpecificContext.java @@ -7,7 +7,6 @@ */ package org.opendaylight.yangtools.yang.parser.stmt.reactor; -import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkState; import static com.google.common.base.Verify.verify; import static com.google.common.base.Verify.verifyNotNull; @@ -29,7 +28,6 @@ import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.common.QNameModule; import org.opendaylight.yangtools.yang.common.XMLNamespace; import org.opendaylight.yangtools.yang.common.YangVersion; -import org.opendaylight.yangtools.yang.model.api.stmt.UnrecognizedStatement; import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier; import org.opendaylight.yangtools.yang.parser.spi.meta.InferenceException; import org.opendaylight.yangtools.yang.parser.spi.meta.ModelActionBuilder; @@ -112,14 +110,8 @@ final class SourceSpecificContext implements NamespaceStorageNode, NamespaceBeha globalContext.putModelDefinedStatementDefinition(name, def); } } - } else if (current != null && current.producesDeclared(UnrecognizedStatement.class)) { - /* - * This code wraps statements encountered inside an extension so - * they do not get confused with regular statements. - */ - def = checkNotNull(current.definition().getAsUnknownStatementDefinition(def), - "Unable to create unknown statement definition of yang statement %s in unknown statement %s", def, - current); + } else if (current != null) { + def = current.definition().overrideDefinition(def); } if (InferenceException.throwIfNull(def, ref, "Statement %s does not have type mapping defined.", name) diff --git a/yang/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/StatementDefinitionContext.java b/yang/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/StatementDefinitionContext.java index 07c63f53e9..32103a339c 100644 --- a/yang/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/StatementDefinitionContext.java +++ b/yang/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.OverrideChildStatementSupport; import org.opendaylight.yangtools.yang.parser.spi.meta.ParserNamespace; import org.opendaylight.yangtools.yang.parser.spi.meta.StatementFactory; import org.opendaylight.yangtools.yang.parser.spi.meta.StatementSupport; @@ -125,24 +126,30 @@ final class StatementDefinitionContext, E exte return support.hasArgumentSpecificSupports(); } - // FIXME: 7.0.0: do we still need this? - StatementDefinitionContext getAsUnknownStatementDefinition( - final StatementDefinitionContext yangStmtDef) { + @NonNull StatementDefinitionContext overrideDefinition( + final @NonNull StatementDefinitionContext def) { + if (!(support instanceof OverrideChildStatementSupport)) { + return def; + } + if (unknownStmtDefsOfYangStmts != null) { - final StatementDefinitionContext existing = unknownStmtDefsOfYangStmts.get(yangStmtDef); + final StatementDefinitionContext existing = unknownStmtDefsOfYangStmts.get(def); if (existing != null) { return existing; } } else { - unknownStmtDefsOfYangStmts = new HashMap<>(); + unknownStmtDefsOfYangStmts = new HashMap<>(4); } - @SuppressWarnings("unchecked") - final StatementDefinitionContext ret = support.getUnknownStatementDefinitionOf( - yangStmtDef.getPublicView()).map(StatementDefinitionContext::new).orElse(null); - if (ret != null) { - unknownStmtDefsOfYangStmts.put(yangStmtDef, ret); + final StatementSupport override = + ((OverrideChildStatementSupport) support).statementDefinitionOverrideOf(def.getPublicView()); + final StatementDefinitionContext ret; + if (override != null) { + ret = new StatementDefinitionContext<>(override); + } else { + ret = def; } + unknownStmtDefsOfYangStmts.put(def, ret); return ret; } } diff --git a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/extension/UnrecognizedStatementSupport.java b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/extension/UnrecognizedStatementSupport.java index d092c896c1..f669707ce1 100644 --- a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/extension/UnrecognizedStatementSupport.java +++ b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/extension/UnrecognizedStatementSupport.java @@ -18,13 +18,14 @@ import org.opendaylight.yangtools.yang.model.api.stmt.UnrecognizedStatement; import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractStatementSupport; import org.opendaylight.yangtools.yang.parser.spi.meta.EffectiveStmtCtx.Current; import org.opendaylight.yangtools.yang.parser.spi.meta.InferenceException; -import org.opendaylight.yangtools.yang.parser.spi.meta.StatementSupport; +import org.opendaylight.yangtools.yang.parser.spi.meta.OverrideChildStatementSupport; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.Mutable; import org.opendaylight.yangtools.yang.parser.spi.meta.SubstatementValidator; final class UnrecognizedStatementSupport - extends AbstractStatementSupport { + extends AbstractStatementSupport + implements OverrideChildStatementSupport { UnrecognizedStatementSupport(final StatementDefinition publicDefinition) { // We have no idea about the statement's semantics, hence there should be noone interested in its semantics. // Nevertheless it may be of interest for various hacks to understand there was an extension involved. @@ -37,20 +38,23 @@ final class UnrecognizedStatementSupport } @Override - public Optional> getUnknownStatementDefinitionOf( - final StatementDefinition yangStmtDef) { + public UnrecognizedStatementSupport statementDefinitionOverrideOf(final StatementDefinition childDef) { + /* + * This code wraps statements encountered inside an extension so they do not get confused with regular + * statements. + */ final QName baseQName = getStatementName(); - final QName statementName = QName.create(baseQName, yangStmtDef.getStatementName().getLocalName()); + final QName statementName = QName.create(baseQName, childDef.getStatementName().getLocalName()); final ModelDefinedStatementDefinition def; - final Optional optArgDef = yangStmtDef.getArgumentDefinition(); + final Optional optArgDef = childDef.getArgumentDefinition(); if (optArgDef.isPresent()) { final ArgumentDefinition argDef = optArgDef.get(); def = new ModelDefinedStatementDefinition(statementName, argDef.getArgumentName(), argDef.isYinElement()); } else { def = new ModelDefinedStatementDefinition(statementName); } - return Optional.of(new UnrecognizedStatementSupport(def)); + return new UnrecognizedStatementSupport(def); } @Override diff --git a/yang/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/OverrideChildStatementSupport.java b/yang/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/OverrideChildStatementSupport.java new file mode 100644 index 0000000000..8a7618c5ba --- /dev/null +++ b/yang/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/OverrideChildStatementSupport.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2021 PANTHEON.tech, s.r.o. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.yangtools.yang.parser.spi.meta; + +import com.google.common.annotations.Beta; +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; +import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition; + +/** + * An additional trait for {@link StatementSupport}, allowing a parent statement to override the support for a child + * statement. + */ +@Beta +public interface OverrideChildStatementSupport { + /** + * Returns unknown statement form of a regular YANG statement supplied as a parameter to the method. + * + * @param childDef statement definition of a regular YANG statement + * @return Optional of unknown statement form of a regular YANG statement, or {@code null} if it should not be + * overridden. + */ + @Nullable StatementSupport statementDefinitionOverrideOf(@NonNull StatementDefinition childDef); +} diff --git a/yang/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StatementSupport.java b/yang/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StatementSupport.java index 464d9e5128..6ea8fe59a2 100644 --- a/yang/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StatementSupport.java +++ b/yang/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StatementSupport.java @@ -408,18 +408,6 @@ public abstract class StatementSupport, E exte return rawArgument; } - /** - * Returns unknown statement form of a regular YANG statement supplied as a parameter to the method. Default - * implementation does nothing. - * - * @param yangStmtDef statement definition of a regular YANG statement - * @return Optional of unknown statement form of a regular YANG statement or empty() if it is not supported by this - * statement support - */ - public Optional> getUnknownStatementDefinitionOf(final StatementDefinition yangStmtDef) { - return Optional.empty(); - } - /** * Returns true if this statement support and all its substatements ignore if-feature statements (e.g. yang-data * extension defined in RFC 8040). Default -- 2.36.6