From: Robert Varga Date: Sun, 31 Jan 2021 12:44:02 +0000 (+0100) Subject: Add CopyPolicy.EXACT_REPLICA X-Git-Tag: v7.0.0~242 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=commitdiff_plain;h=b3660a0741a2b36207e13ef73fff69fe1127c8a5;p=yangtools.git Add CopyPolicy.EXACT_REPLICA There is a slight difference in copy handling of 'type' statement after conversion to CONTEXT_INDEPENDENT -- as that policy ends up being also affected by substatements, which is not correct. Add CopyPolicy.EXACT_REPLICA, which forces the reactor do disregard any substatements' conflicting policy. JIRA: YANGTOOLS-1208 Change-Id: Ib000edf416b706d0c9f3f4c9f292c9b971092c31 Signed-off-by: Robert Varga --- diff --git a/yang/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/StatementContextBase.java b/yang/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/StatementContextBase.java index 84823f6531..dfe906ab88 100644 --- a/yang/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/StatementContextBase.java +++ b/yang/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/StatementContextBase.java @@ -434,21 +434,21 @@ public abstract class StatementContextBase, E } private void summarizeSubstatementPolicy() { - if (noSensitiveSubstatements()) { + if (definition().support().copyPolicy() == CopyPolicy.EXACT_REPLICA || noSensitiveSubstatements()) { setAllSubstatementsContextIndependent(); } } /** - * Determine whether any substatements are context-sensitive as determined by {@link StatementSupport#copyPolicy()}. - * Only {@link CopyPolicy#CONTEXT_INDEPENDENT} and {@link CopyPolicy#IGNORE} are context-insensitive. Note that - * statements which are not {@link StmtContext#isSupportedToBuildEffective()} are all considered - * context-insensitive. + * Determine whether any substatements are copy-sensitive as determined by {@link StatementSupport#copyPolicy()}. + * Only {@link CopyPolicy#CONTEXT_INDEPENDENT}, {@link CopyPolicy#EXACT_REPLICA} and {@link CopyPolicy#IGNORE} are + * copy-insensitive. Note that statements which are not {@link StmtContext#isSupportedToBuildEffective()} are all + * considered copy-insensitive. * *

* Implementations are expected to call {@link #noSensitiveSubstatements()} to actually traverse substatement sets. * - * @return True if no substatements require context-sensitive handling + * @return True if no substatements require copy-sensitive handling */ abstract boolean noSensitiveSubstatements(); @@ -469,6 +469,7 @@ public abstract class StatementContextBase, E switch (stmt.definition().support().copyPolicy()) { case CONTEXT_INDEPENDENT: + case EXACT_REPLICA: case IGNORE: break; default: @@ -654,6 +655,8 @@ public abstract class StatementContextBase, E final StatementSupport support = definition.support(); final CopyPolicy policy = support.copyPolicy(); switch (policy) { + case EXACT_REPLICA: + return replicaAsChildOf(parent); case CONTEXT_INDEPENDENT: if (allSubstatementsContextIndependent()) { return replicaAsChildOf(parent); diff --git a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/type/AbstractIdentityRefSpecificationSupport.java b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/type/AbstractIdentityRefSpecificationSupport.java index 1a021517aa..150fa20e1c 100644 --- a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/type/AbstractIdentityRefSpecificationSupport.java +++ b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/type/AbstractIdentityRefSpecificationSupport.java @@ -35,7 +35,7 @@ abstract class AbstractIdentityRefSpecificationSupport extends AbstractStringStatementSupport> { AbstractIdentityRefSpecificationSupport() { - super(YangStmtMapping.TYPE, StatementPolicy.contextIndependent()); + super(YangStmtMapping.TYPE, StatementPolicy.exactReplica()); } @Override diff --git a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/type/AbstractLeafrefSpecificationSupport.java b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/type/AbstractLeafrefSpecificationSupport.java index c081afb0d6..774a3a1e9f 100644 --- a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/type/AbstractLeafrefSpecificationSupport.java +++ b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/type/AbstractLeafrefSpecificationSupport.java @@ -25,7 +25,7 @@ import org.opendaylight.yangtools.yang.parser.spi.source.SourceException; abstract class AbstractLeafrefSpecificationSupport extends AbstractStringStatementSupport> { AbstractLeafrefSpecificationSupport() { - super(YangStmtMapping.TYPE, StatementPolicy.contextIndependent()); + super(YangStmtMapping.TYPE, StatementPolicy.exactReplica()); } @Override diff --git a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/type/AbstractTypeStatementSupport.java b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/type/AbstractTypeStatementSupport.java index a05b18a35c..c714e12997 100644 --- a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/type/AbstractTypeStatementSupport.java +++ b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/type/AbstractTypeStatementSupport.java @@ -152,7 +152,7 @@ abstract class AbstractTypeStatementSupport Iterables.concat(STATIC_BUILT_IN_TYPES.keySet(), DYNAMIC_BUILT_IN_TYPES.keySet())), key -> key); AbstractTypeStatementSupport() { - super(YangStmtMapping.TYPE, StatementPolicy.contextIndependent()); + super(YangStmtMapping.TYPE, StatementPolicy.exactReplica()); } @Override diff --git a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/type/BitsSpecificationSupport.java b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/type/BitsSpecificationSupport.java index 2159c21ae8..1e84112959 100644 --- a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/type/BitsSpecificationSupport.java +++ b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/type/BitsSpecificationSupport.java @@ -33,7 +33,7 @@ final class BitsSpecificationSupport .build(); BitsSpecificationSupport() { - super(YangStmtMapping.TYPE, StatementPolicy.contextIndependent()); + super(YangStmtMapping.TYPE, StatementPolicy.exactReplica()); } @Override diff --git a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/type/Decimal64SpecificationSupport.java b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/type/Decimal64SpecificationSupport.java index 51c885f6cc..15973bfcec 100644 --- a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/type/Decimal64SpecificationSupport.java +++ b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/type/Decimal64SpecificationSupport.java @@ -32,7 +32,7 @@ final class Decimal64SpecificationSupport extends AbstractStringStatementSupport .build(); Decimal64SpecificationSupport() { - super(YangStmtMapping.TYPE, StatementPolicy.contextIndependent()); + super(YangStmtMapping.TYPE, StatementPolicy.exactReplica()); } @Override diff --git a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/type/EnumSpecificationSupport.java b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/type/EnumSpecificationSupport.java index 23d58431fb..285c899759 100644 --- a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/type/EnumSpecificationSupport.java +++ b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/type/EnumSpecificationSupport.java @@ -31,7 +31,7 @@ final class EnumSpecificationSupport SubstatementValidator.builder(YangStmtMapping.TYPE).addMultiple(YangStmtMapping.ENUM).build(); EnumSpecificationSupport() { - super(YangStmtMapping.TYPE, StatementPolicy.contextIndependent()); + super(YangStmtMapping.TYPE, StatementPolicy.exactReplica()); } @Override diff --git a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/type/InstanceIdentifierSpecificationSupport.java b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/type/InstanceIdentifierSpecificationSupport.java index 82c6fa4975..1f7eba6b73 100644 --- a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/type/InstanceIdentifierSpecificationSupport.java +++ b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/type/InstanceIdentifierSpecificationSupport.java @@ -30,7 +30,7 @@ final class InstanceIdentifierSpecificationSupport .build(); InstanceIdentifierSpecificationSupport() { - super(YangStmtMapping.TYPE, StatementPolicy.contextIndependent()); + super(YangStmtMapping.TYPE, StatementPolicy.exactReplica()); } @Override diff --git a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/type/UnionSpecificationSupport.java b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/type/UnionSpecificationSupport.java index f684c725d2..e4164ac690 100644 --- a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/type/UnionSpecificationSupport.java +++ b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/type/UnionSpecificationSupport.java @@ -31,7 +31,7 @@ final class UnionSpecificationSupport .build(); UnionSpecificationSupport() { - super(YangStmtMapping.TYPE, StatementPolicy.contextIndependent()); + super(YangStmtMapping.TYPE, StatementPolicy.exactReplica()); } @Override diff --git a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/typedef/TypedefStatementSupport.java b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/typedef/TypedefStatementSupport.java index 5eb99e3d85..34e6c2c5af 100644 --- a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/typedef/TypedefStatementSupport.java +++ b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/typedef/TypedefStatementSupport.java @@ -51,7 +51,7 @@ public final class TypedefStatementSupport extends private static final TypedefStatementSupport INSTANCE = new TypedefStatementSupport(); private TypedefStatementSupport() { - super(YangStmtMapping.TYPEDEF, StatementPolicy.contextIndependent()); + super(YangStmtMapping.TYPEDEF, StatementPolicy.exactReplica()); } public static TypedefStatementSupport getInstance() { diff --git a/yang/yang-parser-rfc7950/src/test/java/org/opendaylight/yangtools/yang/stmt/YT1208Test.java b/yang/yang-parser-rfc7950/src/test/java/org/opendaylight/yangtools/yang/stmt/YT1208Test.java index d43f7b82c0..85072b1528 100644 --- a/yang/yang-parser-rfc7950/src/test/java/org/opendaylight/yangtools/yang/stmt/YT1208Test.java +++ b/yang/yang-parser-rfc7950/src/test/java/org/opendaylight/yangtools/yang/stmt/YT1208Test.java @@ -23,6 +23,7 @@ import org.opendaylight.yangtools.yang.model.api.stmt.LeafListEffectiveStatement import org.opendaylight.yangtools.yang.model.api.stmt.ListEffectiveStatement; import org.opendaylight.yangtools.yang.model.api.stmt.ModuleEffectiveStatement; import org.opendaylight.yangtools.yang.model.api.stmt.NotificationEffectiveStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.TypedefEffectiveStatement; public class YT1208Test { @Test @@ -171,4 +172,21 @@ public class YT1208Test { assertSame(contBar, grpBar); } + @Test + public void testTypedefStatementReuse() throws Exception { + final ModuleEffectiveStatement module = StmtTestUtils.parseYangSource("/bugs/YT1208/typedef.yang") + .getModuleStatements() + .get(QNameModule.create(URI.create("foo"))); + assertNotNull(module); + + final TypedefEffectiveStatement grpBar = module + .findFirstEffectiveSubstatement(GroupingEffectiveStatement.class).orElseThrow() + .findFirstEffectiveSubstatement(ContainerEffectiveStatement.class).orElseThrow() + .findFirstEffectiveSubstatement(TypedefEffectiveStatement.class).orElseThrow(); + final TypedefEffectiveStatement contBar = module + .findFirstEffectiveSubstatement(ContainerEffectiveStatement.class).orElseThrow() + .findFirstEffectiveSubstatement(TypedefEffectiveStatement.class).orElseThrow(); + + assertSame(contBar, grpBar); + } } diff --git a/yang/yang-parser-rfc7950/src/test/resources/bugs/YT1208/typedef.yang b/yang/yang-parser-rfc7950/src/test/resources/bugs/YT1208/typedef.yang new file mode 100644 index 0000000000..7466b58af3 --- /dev/null +++ b/yang/yang-parser-rfc7950/src/test/resources/bugs/YT1208/typedef.yang @@ -0,0 +1,22 @@ +module foo { + namespace foo; + prefix foo; + + extension foo; + + grouping grp { + container foo { + typedef bar { + type string; + // This extension must not prevent 'bar' reuse + foo:foo; + } + + leaf baz { + type bar; + } + } + } + + uses grp; +} diff --git a/yang/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StatementSupport.java b/yang/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StatementSupport.java index 241e208aa5..82a3e37fb8 100644 --- a/yang/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StatementSupport.java +++ b/yang/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StatementSupport.java @@ -66,6 +66,18 @@ public abstract class StatementSupport, E exte return (StatementPolicy) EqualSemantics.CONTEXT_INDEPENDENT; } + /** + * Return a {@link StatementPolicy} for {@link CopyPolicy#EXACT_REPLICA}. + * + * @param Argument type + * @param Declared Statement representation + * @return Exact-replica policy + */ + @SuppressWarnings("unchecked") + public static final > @NonNull StatementPolicy exactReplica() { + return (StatementPolicy) EqualSemantics.EXACT_REPLICA; + } + /** * Return a {@link StatementPolicy} for {@link CopyPolicy#IGNORE}. * @@ -145,6 +157,8 @@ public abstract class StatementSupport, E exte new EqualSemantics<>((copy, stmt, substatements) -> false); static final @NonNull EqualSemantics CONTEXT_INDEPENDENT = new EqualSemantics<>(CopyPolicy.CONTEXT_INDEPENDENT, (copy, stmt, substatements) -> true); + static final @NonNull EqualSemantics EXACT_REPLICA = + new EqualSemantics<>(CopyPolicy.EXACT_REPLICA, (copy, stmt, substatements) -> true); private final @NonNull StatementEquality equality; @@ -479,6 +493,13 @@ public abstract class StatementSupport, E exte */ // TODO: does this mean source must have transitioned to ModelProcessingPhase.EFFECTIVE_MODEL? CONTEXT_INDEPENDENT, + /** + * Reuse the source statement context in the new place completely. This policy is more stringent than + * {@link #CONTEXT_INDEPENDENT} in that the statement is dependent on circumstances of its original definition + * and any copy operation must replicate it exactly as is. This implies ignoring the usual policy of its + * substatements. A typical example of such a statement is {@code type}. + */ + EXACT_REPLICA, /** * Create a copy sharing declared instance, but otherwise having a separate disconnected lifecycle. */