Use instantiatedPolicy() for leaf-list statements 88/94888/4
authorRobert Varga <robert.varga@pantheon.tech>
Fri, 29 Jan 2021 20:49:31 +0000 (21:49 +0100)
committerRobert Varga <robert.varga@pantheon.tech>
Fri, 29 Jan 2021 21:31:44 +0000 (22:31 +0100)
The statements are not bringing much to the table, make sure we
use the appropriate policy.

JIRA: YANGTOOLS-1208
Change-Id: I13351a46ef4ed254465ec6f74c5294e1ff540890
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/leaf_list/AbstractLeafListEffectiveStatement.java
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/leaf_list/AbstractNonEmptyLeafListEffectiveStatement.java
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/leaf_list/EmptyLeafListEffectiveStatement.java
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/leaf_list/LeafListStatementSupport.java
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/leaf_list/RegularLeafListEffectiveStatement.java
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/leaf_list/SlimLeafListEffectiveStatement.java
yang/yang-parser-rfc7950/src/test/java/org/opendaylight/yangtools/yang/stmt/YT1208Test.java
yang/yang-parser-rfc7950/src/test/resources/bugs/YT1208/leaflist.yang [new file with mode: 0644]

index 778139d26d9a1efa1532da80641d2d285f4a1fc7..21b68d538d41feb4dec30709fa6bb3a02a37246d 100644 (file)
@@ -51,6 +51,16 @@ abstract class AbstractLeafListEffectiveStatement
         this.type = buildType();
     }
 
+    AbstractLeafListEffectiveStatement(final AbstractLeafListEffectiveStatement original, final SchemaPath path,
+            final int flags) {
+        super(original);
+        this.substatements = original.substatements;
+        this.path = path;
+        this.flags = flags;
+        // TODO: lazy instantiation?
+        this.type = buildType();
+    }
+
     @Override
     public final ImmutableList<? extends EffectiveStatement<?, ?>> effectiveSubstatements() {
         return unmaskList(substatements);
@@ -97,7 +107,7 @@ abstract class AbstractLeafListEffectiveStatement
         final ConcreteTypeBuilder<?> builder = ConcreteTypes.concreteTypeBuilder(typeStmt.getTypeDefinition(),
             getQName());
         for (final EffectiveStatement<?, ?> stmt : effectiveSubstatements()) {
-            // NOTE: 'default' is ommitted here on purpose
+            // NOTE: 'default' is omitted here on purpose
             if (stmt instanceof DescriptionEffectiveStatement) {
                 builder.setDescription(((DescriptionEffectiveStatement)stmt).argument());
             } else if (stmt instanceof ReferenceEffectiveStatement) {
index 950f2bc6c341be732b41a935aaf1796d56f126fa..62ed0440b070124cd8df04d0f864afcc72edb076 100644 (file)
@@ -28,6 +28,13 @@ abstract class AbstractNonEmptyLeafListEffectiveStatement extends AbstractLeafLi
         this.elementCountConstraint = elementCountConstraint;
     }
 
+    AbstractNonEmptyLeafListEffectiveStatement(final AbstractNonEmptyLeafListEffectiveStatement original,
+            final SchemaPath path, final int flags) {
+        super(original, path, flags);
+        this.original = original.original;
+        this.elementCountConstraint = original.elementCountConstraint;
+    }
+
     @Override
     public final Optional<LeafListSchemaNode> getOriginal() {
         return Optional.ofNullable(original);
index 2c6620282eb283bf50a0396d3cca61a5094e27bf..9942c62a99429a2fbede7506fecd8b51d897c870 100644 (file)
@@ -23,6 +23,11 @@ final class EmptyLeafListEffectiveStatement extends AbstractLeafListEffectiveSta
         super(declared, path, flags, substatements);
     }
 
+    EmptyLeafListEffectiveStatement(final EmptyLeafListEffectiveStatement original, final SchemaPath path,
+            final int flags) {
+        super(original, path, flags);
+    }
+
     @Override
     public Optional<LeafSchemaNode> getOriginal() {
         return Optional.empty();
index 6726343a33ee9e1ee45164e563a076e7bdf0ead4..4c0a6c109d07c0b366834fa3ef5cb435669f1a29 100644 (file)
@@ -12,6 +12,7 @@ import static java.util.Objects.requireNonNull;
 import com.google.common.annotations.Beta;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;
+import java.util.Collection;
 import java.util.Optional;
 import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.yangtools.yang.common.Ordering;
@@ -76,7 +77,7 @@ public final class LeafListStatementSupport
     private final SubstatementValidator validator;
 
     private LeafListStatementSupport(final SubstatementValidator validator) {
-        super(YangStmtMapping.LEAF_LIST, StatementPolicy.legacyDeclaredCopy());
+        super(YangStmtMapping.LEAF_LIST, instantiatedPolicy());
         this.validator = requireNonNull(validator);
     }
 
@@ -104,6 +105,25 @@ public final class LeafListStatementSupport
         return new EmptyLeafListStatement(ctx.getArgument());
     }
 
+    @Override
+    public LeafListEffectiveStatement copyEffective(final Current<QName, LeafListStatement> stmt,
+            final LeafListEffectiveStatement original) {
+        final int flags = computeFlags(stmt, original.effectiveSubstatements());
+        if (original instanceof EmptyLeafListEffectiveStatement) {
+            return new EmptyLeafListEffectiveStatement((EmptyLeafListEffectiveStatement) original,
+                stmt.wrapSchemaPath(), flags);
+        } else if (original instanceof SlimLeafListEffectiveStatement) {
+            return new SlimLeafListEffectiveStatement((SlimLeafListEffectiveStatement) original, stmt.wrapSchemaPath(),
+                flags);
+        } else if (original instanceof RegularLeafListEffectiveStatement) {
+            return new RegularLeafListEffectiveStatement((RegularLeafListEffectiveStatement) original,
+                stmt.wrapSchemaPath(), flags);
+        } else {
+            // Safe fallback
+            return super.copyEffective(stmt, original);
+        }
+    }
+
     @Override
     protected LeafListEffectiveStatement createEffective(final Current<QName, LeafListStatement> stmt,
             final ImmutableList<? extends EffectiveStatement<?, ?>> substatements) {
@@ -111,15 +131,7 @@ public final class LeafListStatementSupport
                 findFirstStatement(substatements, TypeEffectiveStatement.class), stmt,
                 "Leaf-list is missing a 'type' statement");
 
-        final LeafListSchemaNode original = (LeafListSchemaNode) stmt.original();
-
-        final int flags = new FlagsBuilder()
-                .setHistory(stmt.history())
-                .setStatus(findFirstArgument(substatements, StatusEffectiveStatement.class, Status.CURRENT))
-                .setConfiguration(stmt.effectiveConfig().asNullable())
-                .setUserOrdered(findFirstArgument(substatements, OrderedByEffectiveStatement.class, Ordering.SYSTEM)
-                    .equals(Ordering.USER))
-                .toFlags();
+        final int flags = computeFlags(stmt, substatements);
         final ImmutableSet<String> defaultValues = substatements.stream()
                 .filter(DefaultEffectiveStatement.class::isInstance)
                 .map(DefaultEffectiveStatement.class::cast)
@@ -137,6 +149,7 @@ public final class LeafListStatementSupport
         final Optional<ElementCountConstraint> elementCountConstraint =
                 EffectiveStmtUtils.createElementCountConstraint(substatements);
 
+        final LeafListSchemaNode original = (LeafListSchemaNode) stmt.original();
         final LeafListStatement declared = stmt.declared();
         final SchemaPath path = stmt.wrapSchemaPath();
         if (defaultValues.isEmpty()) {
@@ -149,4 +162,15 @@ public final class LeafListStatementSupport
         return new RegularLeafListEffectiveStatement(declared, path, flags, substatements, original, defaultValues,
             elementCountConstraint.orElse(null));
     }
+
+    private static int computeFlags(final Current<?, ?> stmt,
+        final Collection<? extends EffectiveStatement<?, ?>> substatements) {
+        return new FlagsBuilder()
+            .setHistory(stmt.history())
+            .setStatus(findFirstArgument(substatements, StatusEffectiveStatement.class, Status.CURRENT))
+            .setConfiguration(stmt.effectiveConfig().asNullable())
+            .setUserOrdered(findFirstArgument(substatements, OrderedByEffectiveStatement.class, Ordering.SYSTEM)
+                .equals(Ordering.USER))
+            .toFlags();
+    }
 }
\ No newline at end of file
index d03f3d01c645b04655eb9d230a59fa2c814ba1c9..ba517973ccc95f4e8e15b86378d10884af6b1b59 100644 (file)
@@ -28,6 +28,12 @@ final class RegularLeafListEffectiveStatement extends AbstractNonEmptyLeafListEf
         this.defaults = requireNonNull(defaults);
     }
 
+    RegularLeafListEffectiveStatement(final RegularLeafListEffectiveStatement original, final SchemaPath path,
+            final int flags) {
+        super(original, path, flags);
+        this.defaults = original.defaults;
+    }
+
     @Override
     public ImmutableSet<String> getDefaults() {
         return defaults;
index fdc7be3d1d40a2b0aee4d47ee04f8839d5a0ad34..bb82a96428c849917d81ce48852aaea9a92652af 100644 (file)
@@ -22,6 +22,11 @@ final class SlimLeafListEffectiveStatement extends AbstractNonEmptyLeafListEffec
         super(declared, path, flags, substatements, original, elementCountConstraint);
     }
 
+    SlimLeafListEffectiveStatement(final SlimLeafListEffectiveStatement original, final SchemaPath path,
+            final int flags) {
+        super(original, path, flags);
+    }
+
     @Override
     public ImmutableSet<String> getDefaults() {
         return ImmutableSet.of();
index 2d37bb7533c08146b2c44c5ae6202d8a3e72a6f9..c0aa06aa61fa09d78cbdbabab4696637a51a0ede 100644 (file)
@@ -19,6 +19,7 @@ import org.opendaylight.yangtools.yang.model.api.stmt.ChoiceEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.ContainerEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.GroupingEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.LeafEffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.LeafListEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.ModuleEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.NotificationEffectiveStatement;
 
@@ -128,4 +129,24 @@ public class YT1208Test {
 
         assertSame(contBar, grpBar);
     }
+
+    @Test
+    public void testLeafListStatementReuse() throws Exception {
+        final ModuleEffectiveStatement module = StmtTestUtils.parseYangSource("/bugs/YT1208/leaflist.yang")
+            .getModuleStatements()
+            .get(QNameModule.create(URI.create("foo")));
+        assertNotNull(module);
+
+        final NotificationEffectiveStatement notif = module
+            .findFirstEffectiveSubstatement(NotificationEffectiveStatement.class).orElseThrow();
+
+        final LeafListEffectiveStatement grpBar = notif
+            .findFirstEffectiveSubstatement(GroupingEffectiveStatement.class).orElseThrow()
+            .findFirstEffectiveSubstatement(LeafListEffectiveStatement.class).orElseThrow();
+        final LeafListEffectiveStatement contBar = notif
+            .findFirstEffectiveSubstatement(ContainerEffectiveStatement.class).orElseThrow()
+            .findFirstEffectiveSubstatement(LeafListEffectiveStatement.class).orElseThrow();
+
+        assertSame(contBar, grpBar);
+    }
 }
diff --git a/yang/yang-parser-rfc7950/src/test/resources/bugs/YT1208/leaflist.yang b/yang/yang-parser-rfc7950/src/test/resources/bugs/YT1208/leaflist.yang
new file mode 100644 (file)
index 0000000..cc94094
--- /dev/null
@@ -0,0 +1,21 @@
+module foo {
+  namespace foo;
+  prefix foo;
+
+  grouping grp {
+    leaf-list bar {
+      type string;
+      description "desc";
+    }
+  }
+
+  notification foo {
+    grouping foo {
+      uses grp;
+    }
+
+    container foo {
+      uses foo;
+    }
+  }
+}