From c135667661ba90e9b76ae29d26393db63bf2f3fb Mon Sep 17 00:00:00 2001 From: Robert Varga Date: Mon, 13 Dec 2021 02:29:52 +0100 Subject: [PATCH] Rework undeclared statement definition Statements which are created without a corresponding declaration should not have a DeclaredStatement footprint. Unfortunately our createEffective() expect a DeclaredStatement to be present. This patch adds another, explicit, avenue to create an EffectiveStatement without having its DeclaredStatement (and rawArgument). We then use this facility to provide our usual Undeclared*EffectiveStatements. JIRA: YANGTOOLS-1372 Change-Id: I6fb5874d720cbf3a139890824c33fddde7196946 Signed-off-by: Robert Varga --- .../model/ri/stmt/EffectiveStatements.java | 19 +- .../model/ri/stmt/ImplicitStatements.java | 53 ---- .../model/ri/stmt/UndeclaredStatements.java | 49 ++++ .../ri/stmt/impl/decl/EmptyCaseStatement.java | 2 +- .../stmt/impl/decl/EmptyInputStatement.java | 2 +- .../stmt/impl/decl/EmptyOutputStatement.java | 2 +- .../decl/EmptyUndeclaredCaseStatement.java | 22 -- .../decl/EmptyUndeclaredInputStatement.java | 22 -- .../decl/EmptyUndeclaredOutputStatement.java | 22 -- .../stmt/impl/decl/RegularCaseStatement.java | 2 +- .../stmt/impl/decl/RegularInputStatement.java | 2 +- .../impl/decl/RegularOutputStatement.java | 2 +- .../decl/RegularUndeclaredCaseStatement.java | 25 -- .../decl/RegularUndeclaredInputStatement.java | 25 -- .../RegularUndeclaredOutputStatement.java | 25 -- .../reactor/AbstractResumedStatement.java | 236 ++++++------------ .../reactor/ForwardingUndeclaredCurrent.java | 128 ++++++++++ .../reactor/InferredStatementContext.java | 14 +- .../parser/stmt/reactor/OriginalStmtCtx.java | 170 +++++++++++++ .../parser/stmt/reactor/ReactorStmtCtx.java | 9 +- .../stmt/reactor/ReplicaStatementContext.java | 2 +- .../stmt/reactor/StatementContextBase.java | 46 ++-- .../parser/stmt/reactor/StatementMap.java | 50 ++-- .../stmt/reactor/SubstatementContext.java | 23 +- .../stmt/reactor/UndeclaredStmtCtx.java | 180 +++++++++++++ .../AbstractImplicitStatementSupport.java | 51 ++-- ...actOperationContainerStatementSupport.java | 41 ++- .../stmt/meta/ActionStatementSupport.java | 2 +- .../stmt/meta/CaseStatementSupport.java | 42 ++-- .../stmt/meta/InputStatementSupport.java | 29 +-- .../stmt/meta/OutputStatementSupport.java | 29 +-- .../stmt/meta/RpcStatementSupport.java | 2 +- .../parser/spi/meta/EffectiveStmtCtx.java | 21 ++ .../yang/parser/spi/meta/StmtContext.java | 24 +- .../spi/meta/UndeclaredStatementFactory.java | 39 +++ 35 files changed, 816 insertions(+), 596 deletions(-) delete mode 100644 model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/ImplicitStatements.java create mode 100644 model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/UndeclaredStatements.java delete mode 100644 model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/decl/EmptyUndeclaredCaseStatement.java delete mode 100644 model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/decl/EmptyUndeclaredInputStatement.java delete mode 100644 model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/decl/EmptyUndeclaredOutputStatement.java delete mode 100644 model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/decl/RegularUndeclaredCaseStatement.java delete mode 100644 model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/decl/RegularUndeclaredInputStatement.java delete mode 100644 model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/decl/RegularUndeclaredOutputStatement.java create mode 100644 parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/ForwardingUndeclaredCurrent.java create mode 100644 parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/OriginalStmtCtx.java create mode 100644 parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/UndeclaredStmtCtx.java create mode 100644 parser/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/UndeclaredStatementFactory.java diff --git a/model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/EffectiveStatements.java b/model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/EffectiveStatements.java index b18c7c591a..0aac30f91b 100644 --- a/model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/EffectiveStatements.java +++ b/model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/EffectiveStatements.java @@ -279,7 +279,7 @@ import org.opendaylight.yangtools.yang.model.ri.stmt.impl.eff.UndeclaredOutputEf import org.opendaylight.yangtools.yang.model.spi.meta.SubstatementIndexingException; /** - * Static entry point to instantiating {@link EffectiveStatement} covered in the {@code RFC7950} metamodel. + * Static entry point to instantiating declared {@link EffectiveStatement} covered in the {@code RFC7950} metamodel. */ @Beta @NonNullByDefault @@ -376,11 +376,6 @@ public final class EffectiveStatements { } } - public static CaseEffectiveStatement createCase(final QName argument, final int flags, - final ImmutableList> substatements) { - return new UndeclaredCaseEffectiveStatement(substatements, argument, flags); - } - public static CaseEffectiveStatement createCase(final CaseStatement declared, final QName argument, final int flags, final ImmutableList> substatements) { return new DeclaredCaseEffectiveStatement(declared, substatements, argument, flags); @@ -550,12 +545,6 @@ public final class EffectiveStatements { } } - public static InputEffectiveStatement createInput(final QName argument, final int flags, - final ImmutableList> substatements) - throws SubstatementIndexingException { - return new UndeclaredInputEffectiveStatement(substatements, argument, flags); - } - public static InputEffectiveStatement createInput(final InputStatement declared, final QName argument, final int flags, final ImmutableList> substatements) throws SubstatementIndexingException { @@ -711,12 +700,6 @@ public final class EffectiveStatements { } } - public static OutputEffectiveStatement createOutput(final QName argument, final int flags, - final ImmutableList> substatements) - throws SubstatementIndexingException { - return new UndeclaredOutputEffectiveStatement(substatements, argument, flags); - } - public static OutputEffectiveStatement createOutput(final OutputStatement declared, final QName argument, final int flags, final ImmutableList> substatements) throws SubstatementIndexingException { diff --git a/model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/ImplicitStatements.java b/model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/ImplicitStatements.java deleted file mode 100644 index 3fc444c642..0000000000 --- a/model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/ImplicitStatements.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2020 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.model.ri.stmt; - -import com.google.common.annotations.Beta; -import com.google.common.collect.ImmutableList; -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.opendaylight.yangtools.yang.common.QName; -import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement; -import org.opendaylight.yangtools.yang.model.api.stmt.CaseStatement; -import org.opendaylight.yangtools.yang.model.api.stmt.InputStatement; -import org.opendaylight.yangtools.yang.model.api.stmt.OutputStatement; -import org.opendaylight.yangtools.yang.model.ri.stmt.impl.decl.EmptyUndeclaredCaseStatement; -import org.opendaylight.yangtools.yang.model.ri.stmt.impl.decl.EmptyUndeclaredInputStatement; -import org.opendaylight.yangtools.yang.model.ri.stmt.impl.decl.EmptyUndeclaredOutputStatement; -import org.opendaylight.yangtools.yang.model.ri.stmt.impl.decl.RegularUndeclaredCaseStatement; -import org.opendaylight.yangtools.yang.model.ri.stmt.impl.decl.RegularUndeclaredInputStatement; -import org.opendaylight.yangtools.yang.model.ri.stmt.impl.decl.RegularUndeclaredOutputStatement; - -/** - * Static entry point to instantiating {@link DeclaredStatements} covered in the {@code RFC7950} metamodel which are - * not really declared, but rather implicit. - */ -@Beta -@NonNullByDefault -public final class ImplicitStatements { - private ImplicitStatements() { - // Hidden on purpose - } - - public static CaseStatement createCase(final QName argument, - final ImmutableList> substatements) { - return substatements.isEmpty() ? new EmptyUndeclaredCaseStatement(argument) - : new RegularUndeclaredCaseStatement(argument, substatements); - } - - public static InputStatement createInput(final QName argument, - final ImmutableList> substatements) { - return substatements.isEmpty() ? new EmptyUndeclaredInputStatement(argument) - : new RegularUndeclaredInputStatement(argument, substatements); - } - - public static OutputStatement createOutput(final QName argument, - final ImmutableList> substatements) { - return substatements.isEmpty() ? new EmptyUndeclaredOutputStatement(argument) - : new RegularUndeclaredOutputStatement(argument, substatements); - } -} diff --git a/model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/UndeclaredStatements.java b/model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/UndeclaredStatements.java new file mode 100644 index 0000000000..71ce1f91b9 --- /dev/null +++ b/model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/UndeclaredStatements.java @@ -0,0 +1,49 @@ +/* + * 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.model.ri.stmt; + +import com.google.common.annotations.Beta; +import com.google.common.collect.ImmutableList; +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.CaseEffectiveStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.InputEffectiveStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.OutputEffectiveStatement; +import org.opendaylight.yangtools.yang.model.ri.stmt.impl.eff.UndeclaredCaseEffectiveStatement; +import org.opendaylight.yangtools.yang.model.ri.stmt.impl.eff.UndeclaredInputEffectiveStatement; +import org.opendaylight.yangtools.yang.model.ri.stmt.impl.eff.UndeclaredOutputEffectiveStatement; +import org.opendaylight.yangtools.yang.model.spi.meta.SubstatementIndexingException; + +/** + * Static entry point to instantiating undeclared {@link EffectiveStatement} covered in the {@code RFC7950} metamodel. + */ +@Beta +@NonNullByDefault +public final class UndeclaredStatements { + private UndeclaredStatements() { + // Hidden on purpose + } + + public static CaseEffectiveStatement createCase(final QName argument, final int flags, + final ImmutableList> substatements) { + return new UndeclaredCaseEffectiveStatement(substatements, argument, flags); + } + + public static InputEffectiveStatement createInput(final QName argument, final int flags, + final ImmutableList> substatements) + throws SubstatementIndexingException { + return new UndeclaredInputEffectiveStatement(substatements, argument, flags); + } + + public static OutputEffectiveStatement createOutput(final QName argument, final int flags, + final ImmutableList> substatements) + throws SubstatementIndexingException { + return new UndeclaredOutputEffectiveStatement(substatements, argument, flags); + } +} diff --git a/model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/decl/EmptyCaseStatement.java b/model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/decl/EmptyCaseStatement.java index aef8b96b91..ab2501da8a 100644 --- a/model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/decl/EmptyCaseStatement.java +++ b/model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/decl/EmptyCaseStatement.java @@ -11,7 +11,7 @@ import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.model.api.stmt.CaseStatement; import org.opendaylight.yangtools.yang.model.spi.meta.AbstractDeclaredStatement.WithQNameArgument; -public class EmptyCaseStatement extends WithQNameArgument implements CaseStatement { +public final class EmptyCaseStatement extends WithQNameArgument implements CaseStatement { public EmptyCaseStatement(final QName argument) { super(argument); } diff --git a/model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/decl/EmptyInputStatement.java b/model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/decl/EmptyInputStatement.java index f4e0842360..85374ec7ec 100644 --- a/model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/decl/EmptyInputStatement.java +++ b/model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/decl/EmptyInputStatement.java @@ -11,7 +11,7 @@ import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.model.api.stmt.InputStatement; import org.opendaylight.yangtools.yang.model.spi.meta.AbstractDeclaredStatement.WithQNameArgument; -public class EmptyInputStatement extends WithQNameArgument implements InputStatement { +public final class EmptyInputStatement extends WithQNameArgument implements InputStatement { public EmptyInputStatement(final QName argument) { super(argument); } diff --git a/model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/decl/EmptyOutputStatement.java b/model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/decl/EmptyOutputStatement.java index 4e96f027a6..e3e8f7bd71 100644 --- a/model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/decl/EmptyOutputStatement.java +++ b/model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/decl/EmptyOutputStatement.java @@ -11,7 +11,7 @@ import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.model.api.stmt.OutputStatement; import org.opendaylight.yangtools.yang.model.spi.meta.AbstractDeclaredStatement.WithQNameArgument; -public class EmptyOutputStatement extends WithQNameArgument implements OutputStatement { +public final class EmptyOutputStatement extends WithQNameArgument implements OutputStatement { public EmptyOutputStatement(final QName argument) { super(argument); } diff --git a/model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/decl/EmptyUndeclaredCaseStatement.java b/model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/decl/EmptyUndeclaredCaseStatement.java deleted file mode 100644 index 72933cd98f..0000000000 --- a/model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/decl/EmptyUndeclaredCaseStatement.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (c) 2020 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.model.ri.stmt.impl.decl; - -import org.opendaylight.yangtools.yang.common.QName; -import org.opendaylight.yangtools.yang.model.api.meta.StatementOrigin; - -public final class EmptyUndeclaredCaseStatement extends EmptyCaseStatement { - public EmptyUndeclaredCaseStatement(final QName argument) { - super(argument); - } - - @Override - public StatementOrigin statementOrigin() { - return StatementOrigin.CONTEXT; - } -} diff --git a/model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/decl/EmptyUndeclaredInputStatement.java b/model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/decl/EmptyUndeclaredInputStatement.java deleted file mode 100644 index 5c91f9699c..0000000000 --- a/model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/decl/EmptyUndeclaredInputStatement.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (c) 2020 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.model.ri.stmt.impl.decl; - -import org.opendaylight.yangtools.yang.common.QName; -import org.opendaylight.yangtools.yang.model.api.meta.StatementOrigin; - -public final class EmptyUndeclaredInputStatement extends EmptyInputStatement { - public EmptyUndeclaredInputStatement(final QName argument) { - super(argument); - } - - @Override - public StatementOrigin statementOrigin() { - return StatementOrigin.CONTEXT; - } -} diff --git a/model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/decl/EmptyUndeclaredOutputStatement.java b/model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/decl/EmptyUndeclaredOutputStatement.java deleted file mode 100644 index e599a3f1cd..0000000000 --- a/model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/decl/EmptyUndeclaredOutputStatement.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (c) 2020 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.model.ri.stmt.impl.decl; - -import org.opendaylight.yangtools.yang.common.QName; -import org.opendaylight.yangtools.yang.model.api.meta.StatementOrigin; - -public final class EmptyUndeclaredOutputStatement extends EmptyOutputStatement { - public EmptyUndeclaredOutputStatement(final QName argument) { - super(argument); - } - - @Override - public StatementOrigin statementOrigin() { - return StatementOrigin.CONTEXT; - } -} diff --git a/model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/decl/RegularCaseStatement.java b/model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/decl/RegularCaseStatement.java index 3eb69eb5ac..5137b20361 100644 --- a/model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/decl/RegularCaseStatement.java +++ b/model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/decl/RegularCaseStatement.java @@ -13,7 +13,7 @@ import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement; import org.opendaylight.yangtools.yang.model.api.stmt.CaseStatement; import org.opendaylight.yangtools.yang.model.spi.meta.AbstractDeclaredStatement.WithQNameArgument.WithSubstatements; -public class RegularCaseStatement extends WithSubstatements implements CaseStatement { +public final class RegularCaseStatement extends WithSubstatements implements CaseStatement { public RegularCaseStatement(final QName argument, final ImmutableList> substatements) { super(argument, substatements); diff --git a/model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/decl/RegularInputStatement.java b/model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/decl/RegularInputStatement.java index 62a884aaf4..f47a1947fc 100644 --- a/model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/decl/RegularInputStatement.java +++ b/model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/decl/RegularInputStatement.java @@ -13,7 +13,7 @@ import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement; import org.opendaylight.yangtools.yang.model.api.stmt.InputStatement; import org.opendaylight.yangtools.yang.model.spi.meta.AbstractDeclaredStatement.WithQNameArgument.WithSubstatements; -public class RegularInputStatement extends WithSubstatements implements InputStatement { +public final class RegularInputStatement extends WithSubstatements implements InputStatement { public RegularInputStatement(final QName argument, final ImmutableList> substatements) { super(argument, substatements); diff --git a/model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/decl/RegularOutputStatement.java b/model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/decl/RegularOutputStatement.java index 86ea4c2c48..d4993db321 100644 --- a/model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/decl/RegularOutputStatement.java +++ b/model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/decl/RegularOutputStatement.java @@ -13,7 +13,7 @@ import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement; import org.opendaylight.yangtools.yang.model.api.stmt.OutputStatement; import org.opendaylight.yangtools.yang.model.spi.meta.AbstractDeclaredStatement.WithQNameArgument.WithSubstatements; -public class RegularOutputStatement extends WithSubstatements implements OutputStatement { +public final class RegularOutputStatement extends WithSubstatements implements OutputStatement { public RegularOutputStatement(final QName argument, final ImmutableList> substatements) { super(argument, substatements); diff --git a/model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/decl/RegularUndeclaredCaseStatement.java b/model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/decl/RegularUndeclaredCaseStatement.java deleted file mode 100644 index 60122b6f5e..0000000000 --- a/model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/decl/RegularUndeclaredCaseStatement.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2020 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.model.ri.stmt.impl.decl; - -import com.google.common.collect.ImmutableList; -import org.opendaylight.yangtools.yang.common.QName; -import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement; -import org.opendaylight.yangtools.yang.model.api.meta.StatementOrigin; - -public final class RegularUndeclaredCaseStatement extends RegularCaseStatement { - public RegularUndeclaredCaseStatement(final QName argument, - final ImmutableList> substatements) { - super(argument, substatements); - } - - @Override - public StatementOrigin statementOrigin() { - return StatementOrigin.CONTEXT; - } -} diff --git a/model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/decl/RegularUndeclaredInputStatement.java b/model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/decl/RegularUndeclaredInputStatement.java deleted file mode 100644 index a8ad0d1d85..0000000000 --- a/model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/decl/RegularUndeclaredInputStatement.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2020 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.model.ri.stmt.impl.decl; - -import com.google.common.collect.ImmutableList; -import org.opendaylight.yangtools.yang.common.QName; -import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement; -import org.opendaylight.yangtools.yang.model.api.meta.StatementOrigin; - -public final class RegularUndeclaredInputStatement extends RegularInputStatement { - public RegularUndeclaredInputStatement(final QName argument, - final ImmutableList> substatements) { - super(argument, substatements); - } - - @Override - public StatementOrigin statementOrigin() { - return StatementOrigin.CONTEXT; - } -} diff --git a/model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/decl/RegularUndeclaredOutputStatement.java b/model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/decl/RegularUndeclaredOutputStatement.java deleted file mode 100644 index 765f3d39f0..0000000000 --- a/model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/decl/RegularUndeclaredOutputStatement.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2020 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.model.ri.stmt.impl.decl; - -import com.google.common.collect.ImmutableList; -import org.opendaylight.yangtools.yang.common.QName; -import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement; -import org.opendaylight.yangtools.yang.model.api.meta.StatementOrigin; - -public final class RegularUndeclaredOutputStatement extends RegularOutputStatement { - public RegularUndeclaredOutputStatement(final QName argument, - final ImmutableList> substatements) { - super(argument, substatements); - } - - @Override - public StatementOrigin statementOrigin() { - return StatementOrigin.CONTEXT; - } -} 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 50fbbcd23c..12d879e2c7 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 @@ -10,29 +10,20 @@ package org.opendaylight.yangtools.yang.parser.stmt.reactor; import static com.google.common.base.Preconditions.checkState; import static com.google.common.base.Verify.verify; import static com.google.common.base.Verify.verifyNotNull; -import static java.util.Objects.requireNonNull; -import com.google.common.collect.ImmutableList; import java.util.Collection; -import java.util.Iterator; -import java.util.List; -import java.util.Optional; import java.util.stream.Stream; 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; -import org.opendaylight.yangtools.yang.model.api.meta.StatementOrigin; -import org.opendaylight.yangtools.yang.parser.spi.meta.CopyType; import org.opendaylight.yangtools.yang.parser.spi.meta.ModelProcessingPhase; +import org.opendaylight.yangtools.yang.parser.spi.meta.StatementFactory; import org.opendaylight.yangtools.yang.parser.spi.meta.StatementSupport; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; -import org.opendaylight.yangtools.yang.parser.spi.source.ImplicitSubstatement; import org.opendaylight.yangtools.yang.parser.spi.source.StatementSourceReference; import org.opendaylight.yangtools.yang.parser.spi.source.StatementWriter.ResumedStatement; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** * Intermediate subclass of StatementContextBase facing the parser stream via implementation of ResumedStatement. This @@ -43,20 +34,15 @@ import org.slf4j.LoggerFactory; * @param Effective Statement representation */ abstract class AbstractResumedStatement, E extends EffectiveStatement> - extends StatementContextBase implements ResumedStatement { - private static final Logger LOG = LoggerFactory.getLogger(AbstractResumedStatement.class); - - private final @NonNull StatementSourceReference statementDeclSource; + extends OriginalStmtCtx implements ResumedStatement { private final String rawArgument; - private List> effective = ImmutableList.of(); private StatementMap substatements = StatementMap.empty(); private @Nullable D declaredInstance; // Copy constructor AbstractResumedStatement(final AbstractResumedStatement original) { super(original); - this.statementDeclSource = original.statementDeclSource; this.rawArgument = original.rawArgument; this.substatements = original.substatements; this.declaredInstance = original.declaredInstance; @@ -64,67 +50,18 @@ abstract class AbstractResumedStatement, E ext AbstractResumedStatement(final StatementDefinitionContext def, final StatementSourceReference ref, final String rawArgument) { - super(def); - this.statementDeclSource = requireNonNull(ref); + super(def, ref); this.rawArgument = def.support().internArgument(rawArgument); } - AbstractResumedStatement(final StatementDefinitionContext def, final StatementSourceReference ref, - final String rawArgument, final CopyType copyType) { - super(def, copyType); - this.statementDeclSource = requireNonNull(ref); - this.rawArgument = rawArgument; - } - - @Override - public final Optional> getOriginalCtx() { - return Optional.empty(); - } - - @Override - public final Optional> getPreviousCopyCtx() { - return Optional.empty(); - } - - @Override - public final StatementSourceReference sourceReference() { - return statementDeclSource; - } - @Override public final String rawArgument() { return rawArgument; } @Override - public final Collection> mutableDeclaredSubstatements() { - return substatements; - } - - @Override - public final Collection> mutableEffectiveSubstatements() { - return mutableEffectiveSubstatements(effective); - } - - @Override - public final void removeStatementFromEffectiveSubstatements(final StatementDefinition statementDef) { - effective = removeStatementFromEffectiveSubstatements(effective, statementDef); - } - - @Override - public final void removeStatementFromEffectiveSubstatements(final StatementDefinition statementDef, - final String statementArg) { - effective = removeStatementFromEffectiveSubstatements(effective, statementDef, statementArg); - } - - @Override - public final void addEffectiveSubstatement(final Mutable substatement) { - effective = addEffectiveSubstatement(effective, substatement); - } - - @Override - final void addEffectiveSubstatementsImpl(final Collection> statements) { - effective = addEffectiveSubstatementsImpl(effective, statements); + public Collection> mutableDeclaredSubstatements() { + return verifyNotNull(substatements); } @Override @@ -140,18 +77,13 @@ abstract class AbstractResumedStatement, E ext return declaredInstance = definition().getFactory().createDeclared(this, substatementsAsDeclared()); } + @SuppressWarnings({ "rawtypes", "unchecked" }) private @NonNull Stream> substatementsAsDeclared() { - var stream = substatements.stream(); + final Stream> stream; if (getImplicitDeclaredFlag()) { - stream = stream.map(stmt -> { - var ret = stmt; - while (ret.origin() == StatementOrigin.CONTEXT) { - final var stmts = ret.substatements; - verify(stmts.size() == 1, "Unexpected substatements %s", stmts); - ret = verifyNotNull(stmts.get(0)); - } - return ret; - }); + stream = substatements.stream().map(AbstractResumedStatement::unmaskUndeclared); + } else { + stream = (Stream) substatements.stream(); } return stream.map(AbstractResumedStatement::declared); @@ -164,7 +96,7 @@ abstract class AbstractResumedStatement, E ext @Override public final StatementSourceReference getSourceReference() { - return statementDeclSource; + return sourceReference(); } @Override @@ -172,6 +104,31 @@ abstract class AbstractResumedStatement, E ext return fullyDefined(); } + @Override + final E createEffective(final StatementFactory factory) { + return createEffective(factory, this); + } + + // Creates EffectiveStatement through full materialization and assumes declared statement presence + private @NonNull E createEffective(final StatementFactory factory, + final StatementContextBase ctx) { + // Statement reference count infrastructure makes an assumption that effective statement is only built after + // the declared statement is already done. Statements tracked by this class always have a declared view, and + // we need to ensure that is built before we touch effective substatements. + // + // Once the effective substatement stream has been exhausted, reference counting will triggers a sweep, hence + // the substatements may be gone by the time the factory attempts to acquire the declared statement. + declared(); + + return factory.createEffective(ctx, ctx.streamDeclared(), ctx.streamEffective()); + } + + @Override + final E createInferredEffective(final StatementFactory factory, + final InferredStatementContext ctx) { + return createEffective(factory, ctx); + } + /** * Create a new substatement at the specified offset. * @@ -193,38 +150,37 @@ abstract class AbstractResumedStatement, E ext checkState(inProgressPhase != ModelProcessingPhase.EFFECTIVE_MODEL, "Declared statement cannot be added in effective phase at: %s", sourceReference()); + final SubstatementContext ret; final var implicitParent = definition().getImplicitParentFor(this, def.getPublicView()); if (implicitParent.isPresent()) { - return createImplicitParent(offset, implicitParent.orElseThrow(), ref, argument) - .createSubstatement(0, def, ref, argument); + setImplicitDeclaredFlag(); + final var parent = createUndeclared(offset, implicitParent.orElseThrow(), ref, argument); + ret = new SubstatementContext<>(parent, def, ref, argument); + parent.addEffectiveSubstatement(ret); + } else { + ret = new SubstatementContext<>(this, def, ref, argument); + substatements = substatements.put(offset, ret); } - final AbstractResumedStatement ret = new SubstatementContext<>(this, def, ref, argument); - substatements = substatements.put(offset, ret); def.onStatementAdded(ret); return ret; } - @Override - final AbstractResumedStatement unmodifiedEffectiveSource() { - // This statement is comes from the source - return this; - } - - @Override - final boolean hasEmptySubstatements() { - return substatements.size() == 0 && effective.isEmpty(); - } - - @Override - final boolean noSensitiveSubstatements() { - return hasEmptySubstatements() - || noSensitiveSubstatements(substatements) && noSensitiveSubstatements(effective); - } - - @Override - final Iterator> effectiveChildrenToComplete() { - return effective.iterator(); + private , Z extends EffectiveStatement> + UndeclaredStmtCtx createUndeclared(final int offset, final StatementSupport support, + final StatementSourceReference ref, final String argument) { + final UndeclaredStmtCtx ret; + final var implicitParent = definition().getImplicitParentFor(this, support.getPublicView()); + if (implicitParent.isPresent()) { + final var parent = createUndeclared(offset, implicitParent.orElseThrow(), ref, argument); + ret = new UndeclaredStmtCtx<>(parent, support, argument); + parent.addEffectiveSubstatement(ret); + } else { + ret = new UndeclaredStmtCtx<>(this, support, argument); + substatements = substatements.put(offset, ret); + } + support.onStatementAdded(ret); + return ret; } @Override @@ -233,31 +189,8 @@ abstract class AbstractResumedStatement, E ext } @Override - final Stream> streamEffective() { - return effective.stream().filter(StmtContext::isSupportedToBuildEffective); - } - - @Override - final void markNoParentRef() { - markNoParentRef(substatements); - markNoParentRef(effective); - } - - @Override - final int sweepSubstatements() { - // First we need to sweep all statements, which may trigger sweeps all across the place, for example: - // - 'effective' member sweeping a 'substatements' member - // - 'substatements' member sweeping a 'substatements' member which came before it during iteration - // We then iterate once again, counting what remains unswept - sweep(substatements); - sweep(effective); - final int count = countUnswept(substatements) + countUnswept(effective); - if (count != 0) { - LOG.debug("{} children left to sweep from {}", count, this); - } + final void dropDeclaredSubstatements() { substatements = null; - effective = null; - return count; } /** @@ -268,13 +201,17 @@ abstract class AbstractResumedStatement, E ext * @return Substatement, or null if substatement does not exist. */ final @Nullable AbstractResumedStatement enterSubstatement(final int offset) { - var ret = substatements.get(offset); - if (ret != null) { - while (ret.origin() == StatementOrigin.CONTEXT) { - ret = verifyNotNull(ret.substatements.get(0)); - } + var stmt = substatements.get(offset); + return stmt == null ? null : unmaskUndeclared(stmt); + } + + private static @NonNull AbstractResumedStatement unmaskUndeclared(final ReactorStmtCtx stmt) { + var ret = stmt; + while (!(ret instanceof AbstractResumedStatement)) { + verify(ret instanceof UndeclaredStmtCtx, "Unexpectred statement %s", ret); + ret = ((UndeclaredStmtCtx) ret).getResumedSubstatement(); } - return ret; + return (AbstractResumedStatement) ret; } /** @@ -292,25 +229,26 @@ abstract class AbstractResumedStatement, E ext var ret = verifyParent(parent); // Unwind all undeclared statements - while (ret.origin() == StatementOrigin.CONTEXT) { + while (!(ret instanceof AbstractResumedStatement)) { ret.finishDeclaration(phase); ret = verifyParent(ret.getParentContext()); } - return ret; + return (AbstractResumedStatement) ret; } - // FIXME: AbstractResumedStatement should only ever have AbstractResumedStatement parents, which would remove the - // need for this method. In ordered to do that we need to untangle SubstatementContext's users and do not - // allow it being reparent()ed. - private static AbstractResumedStatement verifyParent(final StatementContextBase parent) { - verify(parent instanceof AbstractResumedStatement, "Unexpected parent context %s", parent); - return (AbstractResumedStatement) parent; + // FIXME: AbstractResumedStatement should only ever have OriginalStmtCtx parents, which would remove the need for + // this method. In ordered to do that we need to untangle SubstatementContext's users and do not allow it + // being reparent()ed. + private static OriginalStmtCtx verifyParent(final StatementContextBase parent) { + verify(parent instanceof OriginalStmtCtx, "Unexpected parent context %s", parent); + return (OriginalStmtCtx) parent; } final void resizeSubstatements(final int expectedSize) { substatements = substatements.ensureCapacity(expectedSize); } + @Override final void declarationFinished(final ModelProcessingPhase phase) { finishChildrenDeclaration(phase); finishDeclaration(phase); @@ -320,20 +258,4 @@ abstract class AbstractResumedStatement, E ext checkState(isFullyDefined()); substatements.forEach(stmt -> stmt.declarationFinished(phase)); } - - /** - * Ends declared section of current node for the specified phase. - * - * @param phase processing phase that ended - */ - private void finishDeclaration(final ModelProcessingPhase phase) { - definition().onDeclarationFinished(this, phase); - } - - private AbstractResumedStatement createImplicitParent(final int offset, - final StatementSupport implicitParent, final StatementSourceReference ref, final String argument) { - setImplicitDeclaredFlag(); - return createSubstatement(offset, new StatementDefinitionContext<>(implicitParent), - ImplicitSubstatement.of(ref), argument); - } } diff --git a/parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/ForwardingUndeclaredCurrent.java b/parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/ForwardingUndeclaredCurrent.java new file mode 100644 index 0000000000..84ffdd29d3 --- /dev/null +++ b/parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/ForwardingUndeclaredCurrent.java @@ -0,0 +1,128 @@ +/* + * 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.stmt.reactor; + +import static java.util.Objects.requireNonNull; + +import com.google.common.collect.ForwardingObject; +import java.util.Map; +import java.util.Optional; +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.common.YangVersion; +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.parser.spi.meta.CopyHistory; +import org.opendaylight.yangtools.yang.parser.spi.meta.EffectiveStmtCtx.UndeclaredCurrent; +import org.opendaylight.yangtools.yang.parser.spi.meta.ParserNamespace; +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; +import org.opendaylight.yangtools.yang.parser.spi.source.StatementSourceReference; + +final class ForwardingUndeclaredCurrent> extends ForwardingObject + implements UndeclaredCurrent { + private final Current delegate; + + ForwardingUndeclaredCurrent(final Current delegate) { + this.delegate = requireNonNull(delegate); + } + + @Override + public @NonNull QName moduleName() { + return delegate.moduleName(); + } + + @Override + @Deprecated(forRemoval = true) + public EffectiveStatement original() { + return delegate.original(); + } + + @Override + public QName argumentAsTypeQName() { + return delegate.argumentAsTypeQName(); + } + + @Override + @Deprecated + public > StmtContext caerbannog() { + return delegate.caerbannog(); + } + + @Override + public EffectiveConfig effectiveConfig() { + return delegate.effectiveConfig(); + } + + @Override + public QNameModule effectiveNamespace() { + return delegate.effectiveNamespace(); + } + + @Override + public Parent effectiveParent() { + return delegate.effectiveParent(); + } + + @Override + public StatementDefinition publicDefinition() { + return delegate.publicDefinition(); + } + + @Override + public StatementSourceReference sourceReference() { + return delegate.sourceReference(); + } + + @Override + public CopyHistory history() { + return delegate.history(); + } + + @Override + public > Map namespace(final Class<@NonNull N> nsType) { + return delegate.namespace(nsType); + } + + @Override + public > V namespaceItem(final Class<@NonNull N> nsType, + final T key) { + return delegate.namespaceItem(nsType, key); + } + + @Override + public > Map localNamespacePortion(final Class<@NonNull N> nsType) { + return delegate.localNamespacePortion(nsType); + } + + @Override + public A argument() { + return delegate.argument(); + } + + @Override + public YangVersion yangVersion() { + return delegate.yangVersion(); + } + + @Override + public > Optional findSubstatementArgument(final Class type) { + return delegate.findSubstatementArgument(type); + } + + @Override + public boolean hasSubstatement(final Class> type) { + return delegate.hasSubstatement(type); + } + + @Override + protected Current delegate() { + return delegate; + } +} diff --git a/parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/InferredStatementContext.java b/parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/InferredStatementContext.java index c1e4386f21..2d724e8568 100644 --- a/parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/InferredStatementContext.java +++ b/parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/InferredStatementContext.java @@ -211,10 +211,15 @@ final class InferredStatementContext, E extend // If we have not materialized we do not have a difference in effective substatements, hence we can forward // towards the source of the statement. accessSubstatements(); - return substatements == null ? tryToReusePrototype(factory) : super.createEffective(factory); + return substatements == null ? tryToReusePrototype(factory) : createInferredEffective(factory, this); } - private @NonNull E tryToReusePrototype(final StatementFactory factory) { + @Override + E createInferredEffective(final StatementFactory factory, final InferredStatementContext ctx) { + return prototype.createInferredEffective(factory, ctx); + } + + private @NonNull E tryToReusePrototype(final @NonNull StatementFactory factory) { final E origEffective = prototype.buildEffective(); final Collection> origSubstatements = origEffective.effectiveSubstatements(); @@ -276,7 +281,8 @@ final class InferredStatementContext, E extend return internAlongCopyAxis(factory, factory.createEffective(this, declared.stream(), effective.stream())); } - private @NonNull E tryToReuseSubstatements(final StatementFactory factory, final @NonNull E original) { + private @NonNull E tryToReuseSubstatements(final @NonNull StatementFactory factory, + final @NonNull E original) { if (allSubstatementsContextIndependent()) { LOG.debug("Reusing substatements of: {}", prototype); substatements = noRefs() ? REUSED_SUBSTATEMENTS : reusePrototypeReplicas(); @@ -286,7 +292,7 @@ final class InferredStatementContext, E extend // Fall back to full instantiation, which populates our substatements. Then check if we should be reusing // the substatement list, as this operation turned out to not affect them. - final E effective = super.createEffective(factory); + final E effective = createInferredEffective(factory, this); // Since we have forced instantiation to deal with this case, we also need to reset the 'modified' flag setUnmodified(); diff --git a/parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/OriginalStmtCtx.java b/parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/OriginalStmtCtx.java new file mode 100644 index 0000000000..c4c7d95c88 --- /dev/null +++ b/parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/OriginalStmtCtx.java @@ -0,0 +1,170 @@ +/* + * 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.stmt.reactor; + +import static com.google.common.base.Verify.verify; +import static com.google.common.base.Verify.verifyNotNull; +import static java.util.Objects.requireNonNull; + +import com.google.common.collect.ImmutableList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.Optional; +import java.util.stream.Stream; +import org.eclipse.jdt.annotation.NonNull; +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.parser.spi.meta.CopyType; +import org.opendaylight.yangtools.yang.parser.spi.meta.ModelProcessingPhase; +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; +import org.opendaylight.yangtools.yang.parser.spi.source.StatementSourceReference; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +abstract class OriginalStmtCtx, E extends EffectiveStatement> + extends StatementContextBase { + private static final Logger LOG = LoggerFactory.getLogger(OriginalStmtCtx.class); + + private final @NonNull StatementSourceReference ref; + + private List> effective = ImmutableList.of(); + + OriginalStmtCtx(final OriginalStmtCtx original) { + super(original); + this.ref = original.ref; + } + + OriginalStmtCtx(final StatementDefinitionContext def, final StatementSourceReference ref) { + super(def); + this.ref = requireNonNull(ref); + } + + OriginalStmtCtx(final StatementDefinitionContext def, final StatementSourceReference ref, + final CopyType copyType) { + super(def, copyType); + this.ref = requireNonNull(ref); + } + + @Override + public final StatementSourceReference sourceReference() { + return ref; + } + + @Override + public final Optional> getOriginalCtx() { + return Optional.empty(); + } + + @Override + public final Optional> getPreviousCopyCtx() { + return Optional.empty(); + } + + @Override + public final Collection> mutableEffectiveSubstatements() { + return mutableEffectiveSubstatements(effective); + } + + @Override + public final void removeStatementFromEffectiveSubstatements(final StatementDefinition statementDef) { + effective = removeStatementFromEffectiveSubstatements(effective, statementDef); + } + + @Override + public final void removeStatementFromEffectiveSubstatements(final StatementDefinition statementDef, + final String statementArg) { + effective = removeStatementFromEffectiveSubstatements(effective, statementDef, statementArg); + } + + @Override + public final void addEffectiveSubstatement(final Mutable substatement) { + effective = addEffectiveSubstatement(effective, substatement); + } + + @Override + final void addEffectiveSubstatementsImpl(final Collection> statements) { + effective = addEffectiveSubstatementsImpl(effective, statements); + } + + @Override + final Iterator> effectiveChildrenToComplete() { + return effective.iterator(); + } + + @Override + final Stream> streamEffective() { + return effective.stream().filter(StmtContext::isSupportedToBuildEffective); + } + + @Override + final OriginalStmtCtx unmodifiedEffectiveSource() { + // This statement is comes from the source + return this; + } + + @Override + final boolean hasEmptySubstatements() { + return effective.isEmpty() && mutableDeclaredSubstatements().isEmpty(); + } + + @Override + final boolean noSensitiveSubstatements() { + return hasEmptySubstatements() + || noSensitiveSubstatements(effective) && noSensitiveSubstatements(mutableDeclaredSubstatements()); + } + + @Override + final void markNoParentRef() { + markNoParentRef(mutableDeclaredSubstatements()); + markNoParentRef(effective); + } + + @Override + final int sweepSubstatements() { + // First we need to sweep all statements, which may trigger sweeps all across the place, for example: + // - 'effective' member sweeping a 'substatements' member + // - 'substatements' member sweeping a 'substatements' member which came before it during iteration + // We then iterate once again, counting what remains unswept + final var declared = mutableDeclaredSubstatements(); + + sweep(declared); + sweep(effective); + final int count = countUnswept(declared) + countUnswept(effective); + if (count != 0) { + LOG.debug("{} children left to sweep from {}", count, this); + } + effective = null; + dropDeclaredSubstatements(); + return count; + } + + abstract void dropDeclaredSubstatements(); + + void declarationFinished(final ModelProcessingPhase phase) { + finishDeclaration(phase); + } + + /** + * Ends declared section of current node for the specified phase. + * + * @param phase processing phase that ended + */ + final void finishDeclaration(final ModelProcessingPhase phase) { + definition().onDeclarationFinished(this, phase); + } + + final OriginalStmtCtx getResumedSubstatement() { + final var local = verifyNotNull(effective); + verify(!local.isEmpty(), "Unexpected empty statements"); + final var ret = local.get(0); + verify(ret instanceof OriginalStmtCtx, "Unexpected statement %s", ret); + return (OriginalStmtCtx) ret; + } +} diff --git a/parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/ReactorStmtCtx.java b/parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/ReactorStmtCtx.java index 4fd73c7b94..aab4fae60f 100644 --- a/parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/ReactorStmtCtx.java +++ b/parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/ReactorStmtCtx.java @@ -298,8 +298,7 @@ abstract class ReactorStmtCtx, E extends Effec } protected ToStringHelper addToStringAttributes(final ToStringHelper toStringHelper) { - return toStringHelper.add("definition", definition()).add("rawArgument", rawArgument()) - .add("refCount", refString()); + return toStringHelper.add("definition", definition()).add("argument", argument()).add("refCount", refString()); } private String refString() { @@ -389,12 +388,6 @@ abstract class ReactorStmtCtx, E extends Effec } private @NonNull E loadEffective() { - // Creating an effective statement does not strictly require a declared instance -- there are statements like - // 'input', which are implicitly defined. - // Our implementation design makes an invariant assumption that buildDeclared() has been called by the time - // we attempt to create effective statement: - declared(); - final E ret = createEffective(); effectiveInstance = ret; // we have called createEffective(), substatements are no longer guarded by us. Let's see if we can clear up diff --git a/parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/ReplicaStatementContext.java b/parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/ReplicaStatementContext.java index 2f81c12c32..d701912060 100644 --- a/parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/ReplicaStatementContext.java +++ b/parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/ReplicaStatementContext.java @@ -180,7 +180,7 @@ final class ReplicaStatementContext, E extends @Override public , Z extends EffectiveStatement> - Mutable addEffectiveSubstatement(final StatementSupport support, final X arg) { + Mutable addUndeclaredSubstatement(final StatementSupport support, final X arg) { throw new UnsupportedOperationException(); } 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 c5cf622953..f5f85c37c4 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 @@ -49,7 +49,7 @@ import org.opendaylight.yangtools.yang.parser.spi.meta.StatementNamespace; import org.opendaylight.yangtools.yang.parser.spi.meta.StatementSupport; import org.opendaylight.yangtools.yang.parser.spi.meta.StatementSupport.CopyPolicy; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; -import org.opendaylight.yangtools.yang.parser.spi.source.ImplicitSubstatement; +import org.opendaylight.yangtools.yang.parser.spi.meta.UndeclaredStatementFactory; import org.opendaylight.yangtools.yang.parser.spi.source.SourceException; import org.opendaylight.yangtools.yang.parser.stmt.reactor.NamespaceBehaviourWithListeners.KeyedValueAddedListener; import org.opendaylight.yangtools.yang.parser.stmt.reactor.NamespaceBehaviourWithListeners.PredicateValueAddedListener; @@ -321,11 +321,11 @@ abstract class StatementContextBase, E extends @Override public final , Z extends EffectiveStatement> - Mutable addEffectiveSubstatement(final StatementSupport support, final X arg) { - // FIXME: YANGTOOLS-652: This does not need to be a SubstatementContext, in can be a specialized - // StatementContextBase subclass. - final Mutable ret = new SubstatementContext<>(this, new StatementDefinitionContext<>(support), - ImplicitSubstatement.of(sourceReference()), arg); + Mutable addUndeclaredSubstatement(final StatementSupport support, final X arg) { + requireNonNull(support); + checkArgument(support instanceof UndeclaredStatementFactory, "Unsupported statement support %s", support); + + final var ret = new UndeclaredStmtCtx<>(this, support, arg); support.onStatementAdded(ret); addEffectiveSubstatement(ret); return ret; @@ -421,15 +421,20 @@ abstract class StatementContextBase, E extends return result; } - @NonNull E createEffective(final StatementFactory factory) { - return createEffective(factory, this); - } + abstract @NonNull E createEffective(@NonNull StatementFactory factory); - // Creates EffectiveStatement through full materialization - static , E extends EffectiveStatement> @NonNull E createEffective( - final StatementFactory factory, final StatementContextBase ctx) { - return factory.createEffective(ctx, ctx.streamDeclared(), ctx.streamEffective()); - } + /** + * Routing of the request to build an effective statement from {@link InferredStatementContext} towards the original + * definition site. This is needed to pick the correct instantiation method: for declared statements we will + * eventually land in {@link AbstractResumedStatement}, for underclared statements that will be + * {@link UndeclaredStmtCtx}. + * + * @param factory Statement factory + * @param ctx Inferred statement context, i.e. where the effective statement is instantiated + * @return Built effective stateue + */ + abstract @NonNull E createInferredEffective(@NonNull StatementFactory factory, + @NonNull InferredStatementContext ctx); /** * Return a stream of declared statements which can be built into an {@link EffectiveStatement}, as per @@ -795,9 +800,7 @@ abstract class StatementContextBase, E extends final InferredStatementContext copy; if (implicitParent.isPresent()) { - final StatementDefinitionContext def = new StatementDefinitionContext<>(implicitParent.get()); - result = new SubstatementContext(this, def, original.sourceReference(), original.rawArgument(), - original.argument(), type); + result = new UndeclaredStmtCtx(this, implicitParent.orElseThrow(), original, type); final CopyType childCopyType; switch (type) { @@ -846,16 +849,11 @@ abstract class StatementContextBase, E extends return original; } - final StatementDefinitionContext def = new StatementDefinitionContext<>(optImplicit.orElseThrow()); - final CopyType type = original.history().getLastOperation(); - checkArgument(original instanceof StatementContextBase, "Unsupported original %s", original); final var origBase = (StatementContextBase)original; - @SuppressWarnings({ "rawtypes", "unchecked"}) - final SubstatementContext result = new SubstatementContext(origBase.getParentContext(), def, - original.sourceReference(), original.rawArgument(), original.argument(), type); - + @SuppressWarnings({ "rawtypes", "unchecked" }) + final UndeclaredStmtCtx result = new UndeclaredStmtCtx(origBase, optImplicit.orElseThrow()); result.addEffectiveSubstatement(origBase.reparent(result)); result.setCompletedPhase(original.getCompletedPhase()); return result; diff --git a/parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/StatementMap.java b/parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/StatementMap.java index 6441ded70d..fc099716a4 100644 --- a/parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/StatementMap.java +++ b/parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/StatementMap.java @@ -32,15 +32,15 @@ import org.eclipse.jdt.annotation.Nullable; * * @author Robert Varga */ -abstract class StatementMap extends AbstractCollection> { +abstract class StatementMap extends AbstractCollection> { private static final class Empty extends StatementMap { - private static final Iterator> EMPTY_ITERATOR; + private static final Iterator> EMPTY_ITERATOR; static { // This may look weird, but we really want to return two Iterator implementations from StatementMap, so that // users have to deal with bimorphic invocation. Note that we want to invoke hasNext() here, as we want to // initialize state to AbstractIterator.endOfData(). - final Iterator> it = new Regular(0).iterator(); + final Iterator> it = new Regular(0).iterator(); verify(!it.hasNext()); EMPTY_ITERATOR = it; } @@ -51,7 +51,7 @@ abstract class StatementMap extends AbstractCollection obj) { + StatementMap put(final int index, final OriginalStmtCtx obj) { return index == 0 ? new Singleton(obj) : new Regular(index, obj); } @@ -66,48 +66,48 @@ abstract class StatementMap extends AbstractCollection> action) { + public void forEach(final Consumer> action) { // No-op } @Override - public Iterator> iterator() { + public Iterator> iterator() { return EMPTY_ITERATOR; } } private static final class Regular extends StatementMap { - private AbstractResumedStatement[] elements; + private OriginalStmtCtx[] elements; private int size; Regular(final int expectedLimit) { - elements = new AbstractResumedStatement[expectedLimit]; + elements = new OriginalStmtCtx[expectedLimit]; } - Regular(final int index, final AbstractResumedStatement object) { + Regular(final int index, final OriginalStmtCtx object) { this(index + 1, index, object); } - Regular(final AbstractResumedStatement object0, final int index, - final AbstractResumedStatement object) { + Regular(final OriginalStmtCtx object0, final int index, + final OriginalStmtCtx object) { this(index + 1, 0, object0); elements[index] = requireNonNull(object); size = 2; } - Regular(final int expectedLimit, final int index, final AbstractResumedStatement object) { + Regular(final int expectedLimit, final int index, final OriginalStmtCtx object) { this(expectedLimit); elements[index] = requireNonNull(object); size = 1; } @Override - AbstractResumedStatement get(final int index) { + OriginalStmtCtx get(final int index) { return index >= elements.length ? null : elements[index]; } @Override - StatementMap put(final int index, final AbstractResumedStatement obj) { + StatementMap put(final int index, final OriginalStmtCtx obj) { if (index < elements.length) { checkArgument(elements[index] == null); } else { @@ -134,11 +134,11 @@ abstract class StatementMap extends AbstractCollection> iterator() { + public Iterator> iterator() { return new Iter(this); } - private static final class Iter extends AbstractIterator> { + private static final class Iter extends AbstractIterator> { private int nextOffset = 0; private Regular map; @@ -147,9 +147,9 @@ abstract class StatementMap extends AbstractCollection computeNext() { + protected OriginalStmtCtx computeNext() { while (nextOffset < map.elements.length) { - final AbstractResumedStatement ret = map.elements[nextOffset++]; + final OriginalStmtCtx ret = map.elements[nextOffset++]; if (ret != null) { return ret; } @@ -162,19 +162,19 @@ abstract class StatementMap extends AbstractCollection object; + private final OriginalStmtCtx object; - Singleton(final AbstractResumedStatement object) { + Singleton(final OriginalStmtCtx object) { this.object = requireNonNull(object); } @Override - AbstractResumedStatement get(final int index) { + OriginalStmtCtx get(final int index) { return index == 0 ? object : null; } @Override - StatementMap put(final int index, final AbstractResumedStatement obj) { + StatementMap put(final int index, final OriginalStmtCtx obj) { checkArgument(index != 0); return new Regular(object, index, obj); } @@ -190,7 +190,7 @@ abstract class StatementMap extends AbstractCollection> iterator() { + public Iterator> iterator() { return Iterators.singletonIterator(object); } } @@ -212,7 +212,7 @@ abstract class StatementMap extends AbstractCollection get(int index); + abstract @Nullable OriginalStmtCtx get(int index); /** * Add a statement at specified index. @@ -222,7 +222,7 @@ abstract class StatementMap extends AbstractCollection obj); + abstract @NonNull StatementMap put(int index, @NonNull OriginalStmtCtx obj); /** * Ensure storage space for at least {@code explectedLimit} substatements. diff --git a/parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/SubstatementContext.java b/parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/SubstatementContext.java index ca287ad0a1..15044126b7 100644 --- a/parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/SubstatementContext.java +++ b/parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/SubstatementContext.java @@ -11,7 +11,6 @@ import static java.util.Objects.requireNonNull; import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement; import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; -import org.opendaylight.yangtools.yang.parser.spi.meta.CopyType; import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.StorageNodeType; import org.opendaylight.yangtools.yang.parser.spi.source.StatementSourceReference; @@ -23,33 +22,17 @@ final class SubstatementContext, E extends Eff private SubstatementContext(final SubstatementContext original, final StatementContextBase parent) { super(original); - this.parent = requireNonNull(parent, "Parent must not be null"); + this.parent = requireNonNull(parent); this.argument = original.argument; } - SubstatementContext(final StatementContextBase parent, final StatementDefinitionContext def, + SubstatementContext(final OriginalStmtCtx parent, final StatementDefinitionContext def, final StatementSourceReference ref, final String rawArgument) { super(def, ref, rawArgument); - this.parent = requireNonNull(parent, "Parent must not be null"); + this.parent = requireNonNull(parent); this.argument = def.parseArgumentValue(this, rawArgument()); } - SubstatementContext(final StatementContextBase parent, final StatementDefinitionContext def, - final StatementSourceReference ref, final A argument) { - super(def, ref, null); - this.parent = requireNonNull(parent, "Parent must not be null"); - this.argument = argument != null ? argument : def.parseArgumentValue(this, null); - } - - // FIXME: YANGTOOLS-784: this constructor is only called in contexts where a different implementation - // would be more appropriate - SubstatementContext(final StatementContextBase parent, final StatementDefinitionContext def, - final StatementSourceReference ref, final String rawArgument, final A argument, final CopyType copyType) { - super(def, ref, rawArgument, copyType); - this.parent = requireNonNull(parent, "Parent must not be null"); - this.argument = argument; - } - @Override SubstatementContext reparent(final StatementContextBase newParent) { return new SubstatementContext<>(this, newParent); diff --git a/parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/UndeclaredStmtCtx.java b/parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/UndeclaredStmtCtx.java new file mode 100644 index 0000000000..75b3aefb2d --- /dev/null +++ b/parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/UndeclaredStmtCtx.java @@ -0,0 +1,180 @@ +/* + * 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.stmt.reactor; + +import static com.google.common.base.Verify.verify; +import static java.util.Objects.requireNonNull; + +import com.google.common.collect.ImmutableList; +import java.util.Collection; +import java.util.stream.Stream; +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.parser.spi.meta.CopyType; +import org.opendaylight.yangtools.yang.parser.spi.meta.EffectiveStmtCtx.UndeclaredCurrent; +import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.StorageNodeType; +import org.opendaylight.yangtools.yang.parser.spi.meta.StatementFactory; +import org.opendaylight.yangtools.yang.parser.spi.meta.StatementSupport; +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; +import org.opendaylight.yangtools.yang.parser.spi.meta.UndeclaredStatementFactory; +import org.opendaylight.yangtools.yang.parser.spi.source.ImplicitSubstatement; + +/** +/** + * Core reactor statement implementation of {@link Mutable}. + * + * @param Argument type + * @param Declared Statement representation + * @param Effective Statement representation + */ +final class UndeclaredStmtCtx, E extends EffectiveStatement> + extends OriginalStmtCtx implements UndeclaredCurrent { + private final StatementContextBase parent; + private final A argument; + + private UndeclaredStmtCtx(final UndeclaredStmtCtx original, final StatementContextBase parent) { + super(original); + this.parent = requireNonNull(parent); + this.argument = original.argument; + } + + UndeclaredStmtCtx(final StatementContextBase parent, final StatementSupport support, + final @Nullable A argument) { + super(new StatementDefinitionContext<>(support), ImplicitSubstatement.of(parent.sourceReference())); + this.parent = requireNonNull(parent); + this.argument = argument != null ? argument : definition().parseArgumentValue(this, null); + } + + // Exposed for StatementContextBase.wrapWithImplicit() + UndeclaredStmtCtx(final StatementContextBase original, final StatementSupport support) { + super(new StatementDefinitionContext<>(verifySupport(support)), original.sourceReference(), + original.getLastOperation()); + this.parent = original.getParentContext(); + this.argument = castArgument(original); + } + + // Exposed for implicit substatement wrapping in StatementContextBase.childCopyOf() + UndeclaredStmtCtx(final StatementContextBase parent, final StatementSupport support, + final StatementContextBase original, final CopyType type) { + super(new StatementDefinitionContext<>(verifySupport(support)), original.sourceReference(), type); + this.parent = requireNonNull(parent); + this.argument = castArgument(original); + } + + // Exposed for AbstractResumedStatement + UndeclaredStmtCtx(final StatementContextBase parent, final StatementSupport support, + final String rawArgument) { + super(new StatementDefinitionContext<>(support), ImplicitSubstatement.of(parent.sourceReference())); + this.parent = requireNonNull(parent); + this.argument = definition().parseArgumentValue(this, rawArgument); + } + + // FIXME: this assumes original's argument type matches this type... which is true for the only case we + // currently care about (implicit case in choice, which is always triggered by a SchemaTree original), + // but this will need re-visiting + @SuppressWarnings("unchecked") + private static @NonNull A castArgument(final StatementContextBase original) { + return (A) original.getArgument(); + } + + private static T verifySupport(final T support) { + verify(support instanceof UndeclaredStatementFactory, "Unexpected statement support %s", support); + return support; + } + + @Override + public Collection> mutableDeclaredSubstatements() { + return ImmutableList.of(); + } + + @Override + Stream> streamDeclared() { + return Stream.empty(); + } + + @Override + void dropDeclaredSubstatements() { + // No-op + } + + @Override + UndeclaredStmtCtx reparent(final StatementContextBase newParent) { + return new UndeclaredStmtCtx<>(this, newParent); + } + + @Override + E createEffective(final StatementFactory factory) { + return createEffective(factory, this, streamEffective()); + } + + @SuppressWarnings("unchecked") + private static , E extends EffectiveStatement> @NonNull E createEffective( + final @NonNull StatementFactory factory, final @NonNull UndeclaredCurrent ctx, + final @NonNull Stream> substatements) { + verify(factory instanceof UndeclaredStatementFactory, "Unexpected factory %s", factory); + return ((UndeclaredStatementFactory) factory).createUndeclaredEffective(ctx, substatements); + } + + @Override + E createInferredEffective(final StatementFactory factory, final InferredStatementContext ctx) { + return createEffective(factory, new ForwardingUndeclaredCurrent<>(ctx), ctx.streamEffective()); + } + + /* + * KEEP THINGS ORGANIZED! + * + * below methods exist in the same form in InferredStatementContext. If any adjustment is made here, make sure it is + * properly updated there. + */ + @Override + public A argument() { + return argument; + } + + @Override + public StatementContextBase getParentContext() { + return parent; + } + + @Override + public StorageNodeType getStorageNodeType() { + return StorageNodeType.STATEMENT_LOCAL; + } + + @Override + public StatementContextBase getParentNamespaceStorage() { + return parent; + } + + @Override + public RootStatementContext getRoot() { + return parent.getRoot(); + } + + @Override + public EffectiveConfig effectiveConfig() { + return effectiveConfig(parent); + } + + @Override + protected boolean isIgnoringIfFeatures() { + return isIgnoringIfFeatures(parent); + } + + @Override + protected boolean isIgnoringConfig() { + return isIgnoringConfig(parent); + } + + @Override + protected boolean isParentSupportedByFeatures() { + return parent.isSupportedByFeatures(); + } +} diff --git a/parser/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/meta/AbstractImplicitStatementSupport.java b/parser/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/meta/AbstractImplicitStatementSupport.java index 7d834e1153..45bc4aad89 100644 --- a/parser/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/meta/AbstractImplicitStatementSupport.java +++ b/parser/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/meta/AbstractImplicitStatementSupport.java @@ -10,17 +10,20 @@ package org.opendaylight.yangtools.yang.parser.rfc7950.stmt.meta; import static java.util.Objects.requireNonNull; import com.google.common.collect.ImmutableList; +import java.util.stream.Collectors; +import java.util.stream.Stream; import org.eclipse.jdt.annotation.NonNull; import org.opendaylight.yangtools.yang.common.QName; 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.meta.StatementOrigin; import org.opendaylight.yangtools.yang.model.api.stmt.SchemaTreeEffectiveStatement; import org.opendaylight.yangtools.yang.parser.api.YangParserConfiguration; import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractSchemaTreeStatementSupport; -import org.opendaylight.yangtools.yang.parser.spi.meta.EffectiveStmtCtx.Current; +import org.opendaylight.yangtools.yang.parser.spi.meta.EffectiveStmtCtx.UndeclaredCurrent; +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.meta.UndeclaredStatementFactory; /** * A massively-misnamed superclass for statements which are both schema tree participants and can be created as implicit @@ -30,46 +33,22 @@ import org.opendaylight.yangtools.yang.parser.spi.meta.SubstatementValidator; * @param Effective Statement representation */ abstract class AbstractImplicitStatementSupport, - E extends SchemaTreeEffectiveStatement> extends AbstractSchemaTreeStatementSupport { + E extends SchemaTreeEffectiveStatement> extends AbstractSchemaTreeStatementSupport + implements UndeclaredStatementFactory { AbstractImplicitStatementSupport(final StatementDefinition publicDefinition, final StatementPolicy policy, final YangParserConfiguration config, final SubstatementValidator validator) { super(publicDefinition, policy, config, requireNonNull(validator)); } @Override - public final E copyEffective(final Current stmt, final E original) { - final StatementOrigin source = stmt.origin(); - switch (source) { - case CONTEXT: - return copyUndeclaredEffective(stmt, original); - case DECLARATION: - return copyDeclaredEffective(stmt, original); - default: - throw new IllegalStateException("Unhandled statement source " + source); - } + public final E createUndeclaredEffective(final UndeclaredCurrent stmt, + final @NonNull Stream> effectiveSubstatements) { + return createUndeclaredEffective(stmt, buildEffectiveSubstatements(stmt, + statementsToBuild(stmt, effectiveSubstatements + .filter(StmtContext::isSupportedToBuildEffective) + .collect(Collectors.toUnmodifiableList())))); } - @Override - protected E createEffective(final Current stmt, - final ImmutableList> substatements) { - final StatementOrigin origin = stmt.origin(); - switch (origin) { - case CONTEXT: - return createUndeclaredEffective(stmt, substatements); - case DECLARATION: - return createDeclaredEffective(stmt, substatements); - default: - throw new IllegalStateException("Unhandled statement origin " + origin); - } - } - - abstract @NonNull E copyDeclaredEffective(@NonNull Current stmt, @NonNull E original); - - abstract @NonNull E copyUndeclaredEffective(@NonNull Current stmt, @NonNull E original); - - abstract @NonNull E createDeclaredEffective(@NonNull Current stmt, - @NonNull ImmutableList> substatements); - - abstract @NonNull E createUndeclaredEffective(@NonNull Current stmt, - @NonNull ImmutableList> substatements); + abstract @NonNull E createUndeclaredEffective(@NonNull UndeclaredCurrent stmt, + @NonNull ImmutableList> substatements); } diff --git a/parser/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/meta/AbstractOperationContainerStatementSupport.java b/parser/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/meta/AbstractOperationContainerStatementSupport.java index c3266a9e70..a5975fa347 100644 --- a/parser/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/meta/AbstractOperationContainerStatementSupport.java +++ b/parser/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/meta/AbstractOperationContainerStatementSupport.java @@ -26,6 +26,7 @@ import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.EffectiveStmtUtils; import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractQNameStatementSupport; import org.opendaylight.yangtools.yang.parser.spi.meta.EffectiveStatementState; import org.opendaylight.yangtools.yang.parser.spi.meta.EffectiveStmtCtx.Current; +import org.opendaylight.yangtools.yang.parser.spi.meta.EffectiveStmtCtx.UndeclaredCurrent; import org.opendaylight.yangtools.yang.parser.spi.meta.QNameWithFlagsEffectiveStatementState; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils; @@ -55,46 +56,36 @@ abstract class AbstractOperationContainerStatementSupport stmt, final E original) { - return copyDeclaredEffective( - EffectiveStmtUtils.historyAndStatusFlags(stmt.history(), original.effectiveSubstatements()), stmt, - original); - } - - abstract @NonNull E copyDeclaredEffective(int flags, @NonNull Current stmt, - @NonNull E original); - - @Override - final @NonNull E copyUndeclaredEffective(final Current stmt, final E original) { - return copyUndeclaredEffective( - EffectiveStmtUtils.historyAndStatusFlags(stmt.history(), original.effectiveSubstatements()), stmt, - original); - } - - abstract @NonNull E copyUndeclaredEffective(int flags, @NonNull Current stmt, @NonNull E original); - - @Override - final @NonNull E createDeclaredEffective(final Current stmt, + protected final E createEffective(final Current stmt, final ImmutableList> substatements) { try { - return createDeclaredEffective( - EffectiveStmtUtils.historyAndStatusFlags(stmt.history(), substatements), stmt, substatements); + return createEffective(EffectiveStmtUtils.historyAndStatusFlags(stmt.history(), substatements), stmt, + substatements); } catch (SubstatementIndexingException e) { throw new SourceException(e.getMessage(), stmt, e); } } - abstract @NonNull E createDeclaredEffective(int flags, @NonNull Current stmt, + abstract @NonNull E createEffective(int flags, @NonNull Current stmt, @NonNull ImmutableList> substatements); @Override - final E createUndeclaredEffective(final Current stmt, + public final @NonNull E copyEffective(final Current stmt, final E original) { + return copyEffective( + EffectiveStmtUtils.historyAndStatusFlags(stmt.history(), original.effectiveSubstatements()), stmt, + original); + } + + abstract @NonNull E copyEffective(int flags, @NonNull Current stmt, @NonNull E original); + + @Override + final E createUndeclaredEffective(final UndeclaredCurrent stmt, final ImmutableList> substatements) { return createUndeclaredEffective(EffectiveStmtUtils.historyAndStatusFlags(stmt.history(), substatements), stmt, substatements); } - abstract @NonNull E createUndeclaredEffective(int flags, @NonNull Current stmt, + abstract @NonNull E createUndeclaredEffective(int flags, @NonNull UndeclaredCurrent stmt, @NonNull ImmutableList> substatements); @Override diff --git a/parser/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/meta/ActionStatementSupport.java b/parser/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/meta/ActionStatementSupport.java index 14f3f38c15..1d2d5c15e8 100644 --- a/parser/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/meta/ActionStatementSupport.java +++ b/parser/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/meta/ActionStatementSupport.java @@ -132,7 +132,7 @@ public final class ActionStatementSupport extends private static void appendImplicitSubstatement(final Mutable stmt, final QName substatementName) { - stmt.addEffectiveSubstatement( + stmt.addUndeclaredSubstatement( verifyNotNull(stmt.getFromNamespace(StatementSupportNamespace.class, substatementName)), null); } } diff --git a/parser/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/meta/CaseStatementSupport.java b/parser/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/meta/CaseStatementSupport.java index 4496a38b0e..c623e5a142 100644 --- a/parser/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/meta/CaseStatementSupport.java +++ b/parser/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/meta/CaseStatementSupport.java @@ -24,14 +24,13 @@ import org.opendaylight.yangtools.yang.model.api.YangStmtMapping; import org.opendaylight.yangtools.yang.model.api.meta.DeclarationReference; 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.StatementOrigin; import org.opendaylight.yangtools.yang.model.api.stmt.CaseEffectiveStatement; import org.opendaylight.yangtools.yang.model.api.stmt.CaseStatement; import org.opendaylight.yangtools.yang.model.api.stmt.StatusEffectiveStatement; import org.opendaylight.yangtools.yang.model.ri.stmt.DeclaredStatementDecorators; import org.opendaylight.yangtools.yang.model.ri.stmt.DeclaredStatements; import org.opendaylight.yangtools.yang.model.ri.stmt.EffectiveStatements; -import org.opendaylight.yangtools.yang.model.ri.stmt.ImplicitStatements; +import org.opendaylight.yangtools.yang.model.ri.stmt.UndeclaredStatements; import org.opendaylight.yangtools.yang.model.spi.meta.EffectiveStatementMixins.EffectiveStatementWithFlags.FlagsBuilder; import org.opendaylight.yangtools.yang.model.spi.meta.SubstatementIndexingException; import org.opendaylight.yangtools.yang.parser.api.YangParserConfiguration; @@ -39,6 +38,7 @@ import org.opendaylight.yangtools.yang.parser.spi.meta.BoundStmtCtx; import org.opendaylight.yangtools.yang.parser.spi.meta.EffectiveStatementState; import org.opendaylight.yangtools.yang.parser.spi.meta.EffectiveStmtCtx.Current; import org.opendaylight.yangtools.yang.parser.spi.meta.EffectiveStmtCtx.Parent.EffectiveConfig; +import org.opendaylight.yangtools.yang.parser.spi.meta.EffectiveStmtCtx.UndeclaredCurrent; import org.opendaylight.yangtools.yang.parser.spi.meta.QNameWithFlagsEffectiveStatementState; import org.opendaylight.yangtools.yang.parser.spi.meta.SubstatementValidator; import org.opendaylight.yangtools.yang.parser.spi.source.SourceException; @@ -91,15 +91,7 @@ public final class CaseStatementSupport @Override protected CaseStatement createDeclared(final BoundStmtCtx ctx, final ImmutableList> substatements) { - final StatementOrigin origin = ctx.origin(); - switch (origin) { - case CONTEXT: - return ImplicitStatements.createCase(ctx.getArgument(), substatements); - case DECLARATION: - return DeclaredStatements.createCase(ctx.getArgument(), substatements); - default: - throw new IllegalStateException("Unhandled statement origin " + origin); - } + return DeclaredStatements.createCase(ctx.getArgument(), substatements); } @Override @@ -108,21 +100,7 @@ public final class CaseStatementSupport } @Override - protected CaseEffectiveStatement copyDeclaredEffective(final Current stmt, - final CaseEffectiveStatement original) { - return EffectiveStatements.copyCase(original, stmt.getArgument(), - computeFlags(stmt, original.effectiveSubstatements())); - } - - @Override - protected CaseEffectiveStatement copyUndeclaredEffective(final Current stmt, - final CaseEffectiveStatement original) { - return EffectiveStatements.copyCase(original, stmt.getArgument(), - computeFlags(stmt, original.effectiveSubstatements())); - } - - @Override - protected CaseEffectiveStatement createDeclaredEffective(final Current stmt, + protected CaseEffectiveStatement createEffective(final Current stmt, final ImmutableList> substatements) { try { return EffectiveStatements.createCase(stmt.declared(), stmt.getArgument(), @@ -133,10 +111,18 @@ public final class CaseStatementSupport } @Override - protected CaseEffectiveStatement createUndeclaredEffective(final Current stmt, + public CaseEffectiveStatement copyEffective(final Current stmt, + final CaseEffectiveStatement original) { + return EffectiveStatements.copyCase(original, stmt.getArgument(), + computeFlags(stmt, original.effectiveSubstatements())); + } + + @Override + protected CaseEffectiveStatement createUndeclaredEffective(final UndeclaredCurrent stmt, final ImmutableList> substatements) { try { - return EffectiveStatements.createCase(stmt.getArgument(), computeFlags(stmt, substatements), substatements); + return UndeclaredStatements.createCase(stmt.getArgument(), computeFlags(stmt, substatements), + substatements); } catch (SubstatementIndexingException e) { throw new SourceException(e.getMessage(), stmt, e); } diff --git a/parser/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/meta/InputStatementSupport.java b/parser/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/meta/InputStatementSupport.java index ba6512a9d1..75d9413c3f 100644 --- a/parser/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/meta/InputStatementSupport.java +++ b/parser/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/meta/InputStatementSupport.java @@ -16,17 +16,17 @@ import org.opendaylight.yangtools.yang.model.api.YangStmtMapping; import org.opendaylight.yangtools.yang.model.api.meta.DeclarationReference; 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.StatementOrigin; import org.opendaylight.yangtools.yang.model.api.stmt.InputEffectiveStatement; import org.opendaylight.yangtools.yang.model.api.stmt.InputStatement; import org.opendaylight.yangtools.yang.model.ri.stmt.DeclaredStatementDecorators; import org.opendaylight.yangtools.yang.model.ri.stmt.DeclaredStatements; import org.opendaylight.yangtools.yang.model.ri.stmt.EffectiveStatements; -import org.opendaylight.yangtools.yang.model.ri.stmt.ImplicitStatements; +import org.opendaylight.yangtools.yang.model.ri.stmt.UndeclaredStatements; import org.opendaylight.yangtools.yang.model.spi.meta.SubstatementIndexingException; import org.opendaylight.yangtools.yang.parser.api.YangParserConfiguration; import org.opendaylight.yangtools.yang.parser.spi.meta.BoundStmtCtx; import org.opendaylight.yangtools.yang.parser.spi.meta.EffectiveStmtCtx.Current; +import org.opendaylight.yangtools.yang.parser.spi.meta.EffectiveStmtCtx.UndeclaredCurrent; import org.opendaylight.yangtools.yang.parser.spi.meta.SubstatementValidator; import org.opendaylight.yangtools.yang.parser.spi.source.SourceException; @@ -73,15 +73,7 @@ public final class InputStatementSupport @Override protected InputStatement createDeclared(final BoundStmtCtx ctx, final ImmutableList> substatements) { - final StatementOrigin origin = ctx.origin(); - switch (origin) { - case CONTEXT: - return ImplicitStatements.createInput(ctx.getArgument(), substatements); - case DECLARATION: - return DeclaredStatements.createInput(ctx.getArgument(), substatements); - default: - throw new IllegalStateException("Unhandled statement origin " + origin); - } + return DeclaredStatements.createInput(ctx.getArgument(), substatements); } @Override @@ -91,19 +83,13 @@ public final class InputStatementSupport } @Override - InputEffectiveStatement copyDeclaredEffective(final int flags, final Current stmt, - final InputEffectiveStatement original) { - return EffectiveStatements.copyInput(original, stmt.getArgument(), flags); - } - - @Override - InputEffectiveStatement copyUndeclaredEffective(final int flags, final Current stmt, + InputEffectiveStatement copyEffective(final int flags, final Current stmt, final InputEffectiveStatement original) { return EffectiveStatements.copyInput(original, stmt.getArgument(), flags); } @Override - InputEffectiveStatement createDeclaredEffective(final int flags, final Current stmt, + InputEffectiveStatement createEffective(final int flags, final Current stmt, final ImmutableList> substatements) { try { return EffectiveStatements.createInput(stmt.declared(), stmt.getArgument(), flags, substatements); @@ -113,10 +99,11 @@ public final class InputStatementSupport } @Override - InputEffectiveStatement createUndeclaredEffective(final int flags, final Current stmt, + InputEffectiveStatement createUndeclaredEffective(final int flags, + final UndeclaredCurrent stmt, final ImmutableList> substatements) { try { - return EffectiveStatements.createInput(stmt.getArgument(), flags, substatements); + return UndeclaredStatements.createInput(stmt.getArgument(), flags, substatements); } catch (SubstatementIndexingException e) { throw new SourceException(e.getMessage(), stmt, e); } diff --git a/parser/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/meta/OutputStatementSupport.java b/parser/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/meta/OutputStatementSupport.java index 36294fedd0..72eec151e7 100644 --- a/parser/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/meta/OutputStatementSupport.java +++ b/parser/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/meta/OutputStatementSupport.java @@ -16,17 +16,17 @@ import org.opendaylight.yangtools.yang.model.api.YangStmtMapping; import org.opendaylight.yangtools.yang.model.api.meta.DeclarationReference; 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.StatementOrigin; import org.opendaylight.yangtools.yang.model.api.stmt.OutputEffectiveStatement; import org.opendaylight.yangtools.yang.model.api.stmt.OutputStatement; import org.opendaylight.yangtools.yang.model.ri.stmt.DeclaredStatementDecorators; import org.opendaylight.yangtools.yang.model.ri.stmt.DeclaredStatements; import org.opendaylight.yangtools.yang.model.ri.stmt.EffectiveStatements; -import org.opendaylight.yangtools.yang.model.ri.stmt.ImplicitStatements; +import org.opendaylight.yangtools.yang.model.ri.stmt.UndeclaredStatements; import org.opendaylight.yangtools.yang.model.spi.meta.SubstatementIndexingException; import org.opendaylight.yangtools.yang.parser.api.YangParserConfiguration; import org.opendaylight.yangtools.yang.parser.spi.meta.BoundStmtCtx; import org.opendaylight.yangtools.yang.parser.spi.meta.EffectiveStmtCtx.Current; +import org.opendaylight.yangtools.yang.parser.spi.meta.EffectiveStmtCtx.UndeclaredCurrent; import org.opendaylight.yangtools.yang.parser.spi.meta.SubstatementValidator; import org.opendaylight.yangtools.yang.parser.spi.source.SourceException; @@ -73,15 +73,7 @@ public final class OutputStatementSupport @Override protected OutputStatement createDeclared(final BoundStmtCtx ctx, final ImmutableList> substatements) { - final StatementOrigin origin = ctx.origin(); - switch (origin) { - case CONTEXT: - return ImplicitStatements.createOutput(ctx.getArgument(), substatements); - case DECLARATION: - return DeclaredStatements.createOutput(ctx.getArgument(), substatements); - default: - throw new IllegalStateException("Unhandled statement origin " + origin); - } + return DeclaredStatements.createOutput(ctx.getArgument(), substatements); } @Override @@ -91,19 +83,13 @@ public final class OutputStatementSupport } @Override - OutputEffectiveStatement copyDeclaredEffective(final int flags, final Current stmt, - final OutputEffectiveStatement original) { - return EffectiveStatements.copyOutput(original, stmt.getArgument(), flags); - } - - @Override - OutputEffectiveStatement copyUndeclaredEffective(final int flags, final Current stmt, + OutputEffectiveStatement copyEffective(final int flags, final Current stmt, final OutputEffectiveStatement original) { return EffectiveStatements.copyOutput(original, stmt.getArgument(), flags); } @Override - OutputEffectiveStatement createDeclaredEffective(final int flags, final Current stmt, + OutputEffectiveStatement createEffective(final int flags, final Current stmt, final ImmutableList> substatements) { try { return EffectiveStatements.createOutput(stmt.declared(), stmt.getArgument(), flags, substatements); @@ -113,10 +99,11 @@ public final class OutputStatementSupport } @Override - OutputEffectiveStatement createUndeclaredEffective(final int flags, final Current stmt, + OutputEffectiveStatement createUndeclaredEffective(final int flags, + final UndeclaredCurrent stmt, final ImmutableList> substatements) { try { - return EffectiveStatements.createOutput(stmt.getArgument(), flags, substatements); + return UndeclaredStatements.createOutput(stmt.getArgument(), flags, substatements); } catch (SubstatementIndexingException e) { throw new SourceException(e.getMessage(), stmt, e); } diff --git a/parser/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/meta/RpcStatementSupport.java b/parser/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/meta/RpcStatementSupport.java index 66009ec426..b696325e4d 100644 --- a/parser/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/meta/RpcStatementSupport.java +++ b/parser/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/meta/RpcStatementSupport.java @@ -100,7 +100,7 @@ public final class RpcStatementSupport extends AbstractSchemaTreeStatementSuppor private static void appendImplicitSubstatement(final Mutable stmt, final QName substatementName) { - stmt.addEffectiveSubstatement( + stmt.addUndeclaredSubstatement( verifyNotNull(stmt.getFromNamespace(StatementSupportNamespace.class, substatementName)), null); } } diff --git a/parser/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/EffectiveStmtCtx.java b/parser/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/EffectiveStmtCtx.java index 2140b7dceb..c98c9fa14d 100644 --- a/parser/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/EffectiveStmtCtx.java +++ b/parser/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/EffectiveStmtCtx.java @@ -126,4 +126,25 @@ public interface EffectiveStmtCtx extends CommonStmtCtx, StmtContextCompat, Immu @Deprecated > @NonNull StmtContext caerbannog(); } + + /** + * A restricted version of {@link Current}, which does not expose the raw argument or the declared statement. + * + * @param Argument type + * @param Class representing declared version of this statement + */ + @Beta + interface UndeclaredCurrent> extends Current { + @Deprecated + @Override + default String rawArgument() { + throw new UnsupportedOperationException(); + } + + @Deprecated + @Override + default D declared() { + throw new UnsupportedOperationException(); + } + } } diff --git a/parser/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StmtContext.java b/parser/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StmtContext.java index 96d26f7c0c..d689406428 100644 --- a/parser/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StmtContext.java +++ b/parser/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StmtContext.java @@ -354,17 +354,12 @@ public interface StmtContext, E extends Effect */ void addRequiredSource(SourceIdentifier dependency); - // YANG example: RPC/action statements always have 'input' and 'output' defined - @Beta - , Z extends EffectiveStatement> - @NonNull Mutable addEffectiveSubstatement(StatementSupport support, @Nullable X arg); - /** * Adds an effective statement to collection of substatements. * * @param substatement substatement * @throws IllegalStateException if added in declared phase - * @throws NullPointerException if statement parameter is null + * @throws NullPointerException if {@code substatement} is null */ void addEffectiveSubstatement(Mutable substatement); @@ -377,6 +372,23 @@ public interface StmtContext, E extends Effect */ void addEffectiveSubstatements(Collection> statements); + /** + * Adds a purely-effective statement to collection of substatements. The statement will report a {@code null} + * {@link EffectiveStatement#getDeclared()} object. A typical example of statements which require this mechanics + * are {@code rpc} and {@code action} statements, which always have {@code input} and {@code output} + * substatements, even if those are not declared in YANG text. + * + * @param support Statement support of the statement being created + * @param arg Effective argument. If specified as {@code null}, statement support will be consulted for the + * empty argument. + * @throws IllegalArgumentException if {@code support} does not implement {@link UndeclaredStatementFactory} + * @throws IllegalStateException if added in declared phase + * @throws NullPointerException if {@code support} is null + */ + @Beta + , Z extends EffectiveStatement> + @NonNull Mutable addUndeclaredSubstatement(StatementSupport support, @Nullable X arg); + @Beta void removeStatementFromEffectiveSubstatements(StatementDefinition statementDef); diff --git a/parser/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/UndeclaredStatementFactory.java b/parser/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/UndeclaredStatementFactory.java new file mode 100644 index 0000000000..f80b2f9e81 --- /dev/null +++ b/parser/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/UndeclaredStatementFactory.java @@ -0,0 +1,39 @@ +/* + * 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 java.util.stream.Stream; +import org.eclipse.jdt.annotation.NonNull; +import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement; +import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; +import org.opendaylight.yangtools.yang.parser.spi.meta.EffectiveStmtCtx.Current; +import org.opendaylight.yangtools.yang.parser.spi.meta.EffectiveStmtCtx.UndeclaredCurrent; + +/** + * An entity capable of creating undeclared {@link EffectiveStatement} instances for a particular type. Unlike + * {@link StatementFactory}, effective statements created through this interface are expected to return a {@code null} + * from {@link EffectiveStatement#getDeclared()}. + * + * @param Argument type + * @param Declared Statement representation + * @param Effective Statement representation + */ +@Beta +public interface UndeclaredStatementFactory, E extends EffectiveStatement> { + /** + * Create a {@link EffectiveStatement} for specified context. Implementations of this method must not access + * {@link Current#declared()} or {@link Current#rawArgument()}. + * + * @param stmt Effective capture of this statement's significant state + * @param effectiveSubstatements effectively-visible substatements + * @return An effective statement instance + */ + @NonNull E createUndeclaredEffective(@NonNull UndeclaredCurrent stmt, + @NonNull Stream> effectiveSubstatements); +} -- 2.36.6