}
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.
*
* <p>
* 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();
switch (stmt.definition().support().copyPolicy()) {
case CONTEXT_INDEPENDENT:
+ case EXACT_REPLICA:
case IGNORE:
break;
default:
final StatementSupport<A, D, E> support = definition.support();
final CopyPolicy policy = support.copyPolicy();
switch (policy) {
+ case EXACT_REPLICA:
+ return replicaAsChildOf(parent);
case CONTEXT_INDEPENDENT:
if (allSubstatementsContextIndependent()) {
return replicaAsChildOf(parent);
extends AbstractStringStatementSupport<IdentityRefSpecification,
EffectiveStatement<String, IdentityRefSpecification>> {
AbstractIdentityRefSpecificationSupport() {
- super(YangStmtMapping.TYPE, StatementPolicy.contextIndependent());
+ super(YangStmtMapping.TYPE, StatementPolicy.exactReplica());
}
@Override
abstract class AbstractLeafrefSpecificationSupport extends AbstractStringStatementSupport<LeafrefSpecification,
EffectiveStatement<String, LeafrefSpecification>> {
AbstractLeafrefSpecificationSupport() {
- super(YangStmtMapping.TYPE, StatementPolicy.contextIndependent());
+ super(YangStmtMapping.TYPE, StatementPolicy.exactReplica());
}
@Override
Iterables.<String>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
.build();
BitsSpecificationSupport() {
- super(YangStmtMapping.TYPE, StatementPolicy.contextIndependent());
+ super(YangStmtMapping.TYPE, StatementPolicy.exactReplica());
}
@Override
.build();
Decimal64SpecificationSupport() {
- super(YangStmtMapping.TYPE, StatementPolicy.contextIndependent());
+ super(YangStmtMapping.TYPE, StatementPolicy.exactReplica());
}
@Override
SubstatementValidator.builder(YangStmtMapping.TYPE).addMultiple(YangStmtMapping.ENUM).build();
EnumSpecificationSupport() {
- super(YangStmtMapping.TYPE, StatementPolicy.contextIndependent());
+ super(YangStmtMapping.TYPE, StatementPolicy.exactReplica());
}
@Override
.build();
InstanceIdentifierSpecificationSupport() {
- super(YangStmtMapping.TYPE, StatementPolicy.contextIndependent());
+ super(YangStmtMapping.TYPE, StatementPolicy.exactReplica());
}
@Override
.build();
UnionSpecificationSupport() {
- super(YangStmtMapping.TYPE, StatementPolicy.contextIndependent());
+ super(YangStmtMapping.TYPE, StatementPolicy.exactReplica());
}
@Override
private static final TypedefStatementSupport INSTANCE = new TypedefStatementSupport();
private TypedefStatementSupport() {
- super(YangStmtMapping.TYPEDEF, StatementPolicy.contextIndependent());
+ super(YangStmtMapping.TYPEDEF, StatementPolicy.exactReplica());
}
public static TypedefStatementSupport getInstance() {
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
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);
+ }
}
--- /dev/null
+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;
+}
return (StatementPolicy<A, D>) EqualSemantics.CONTEXT_INDEPENDENT;
}
+ /**
+ * Return a {@link StatementPolicy} for {@link CopyPolicy#EXACT_REPLICA}.
+ *
+ * @param <A> Argument type
+ * @param <D> Declared Statement representation
+ * @return Exact-replica policy
+ */
+ @SuppressWarnings("unchecked")
+ public static final <A, D extends DeclaredStatement<A>> @NonNull StatementPolicy<A, D> exactReplica() {
+ return (StatementPolicy<A, D>) EqualSemantics.EXACT_REPLICA;
+ }
+
/**
* Return a {@link StatementPolicy} for {@link CopyPolicy#IGNORE}.
*
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<A, D> equality;
*/
// 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.
*/