Integrate DataNormalizationOperation with SchemaInferenceStack 41/100241/6
authorRobert Varga <robert.varga@pantheon.tech>
Thu, 24 Mar 2022 13:31:42 +0000 (14:31 +0100)
committerRobert Varga <robert.varga@pantheon.tech>
Fri, 25 Mar 2022 14:25:02 +0000 (15:25 +0100)
This is a backport of changes made for YANGTOOLS-1412, adjusted to the
legacy code in bierman02. These will allow us to use a proper inference.

JIRA: NETCONF-818
Change-Id: Ia3234443e26ff985b823e92d942262dfdeeef29e
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
restconf/restconf-nb-bierman02/src/main/java/org/opendaylight/netconf/sal/restconf/impl/DataNormalizationOperation.java

index 8a38c842bda3b0227871f3faf0974616d2bd35c4..28e933bc304edbd0b4e9831784393fffeb4a916f 100644 (file)
@@ -7,6 +7,8 @@
  */
 package org.opendaylight.netconf.sal.restconf.impl;
 
+import static com.google.common.base.Verify.verifyNotNull;
+
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Iterables;
@@ -38,6 +40,7 @@ import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
 import org.opendaylight.yangtools.yang.model.util.EffectiveAugmentationSchema;
+import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack;
 
 abstract class DataNormalizationOperation<T extends PathArgument> implements Identifiable<T> {
     private final T identifier;
@@ -67,6 +70,17 @@ abstract class DataNormalizationOperation<T extends PathArgument> implements Ide
 
     abstract DataNormalizationOperation<?> getChild(QName child) throws DataNormalizationException;
 
+    abstract DataNormalizationOperation<?> enterChild(QName child, SchemaInferenceStack stack)
+        throws DataNormalizationException;
+
+    abstract DataNormalizationOperation<?> enterChild(PathArgument child, SchemaInferenceStack stack)
+        throws DataNormalizationException;
+
+    void pushToStack(final SchemaInferenceStack stack) {
+        // Accurate for most subclasses
+        stack.enterSchemaTree(getIdentifier().getNodeType());
+    }
+
     private abstract static class SimpleTypeNormalization<T extends PathArgument>
             extends DataNormalizationOperation<T> {
         SimpleTypeNormalization(final T identifier) {
@@ -82,6 +96,16 @@ abstract class DataNormalizationOperation<T extends PathArgument> implements Ide
         final DataNormalizationOperation<?> getChild(final QName child) {
             return null;
         }
+
+        @Override
+        final DataNormalizationOperation<?> enterChild(final QName child, final SchemaInferenceStack stack) {
+            return null;
+        }
+
+        @Override
+        final DataNormalizationOperation<?> enterChild(final PathArgument child, final SchemaInferenceStack stack) {
+            return null;
+        }
     }
 
     private static final class LeafNormalization extends SimpleTypeNormalization<NodeIdentifier> {
@@ -94,6 +118,11 @@ abstract class DataNormalizationOperation<T extends PathArgument> implements Ide
         LeafListEntryNormalization(final LeafListSchemaNode potential) {
             super(new NodeWithValue<>(potential.getQName(), Empty.value()));
         }
+
+        @Override
+        protected void pushToStack(final SchemaInferenceStack stack) {
+            // No-op
+        }
     }
 
     private abstract static class DataContainerNormalizationOperation<T extends PathArgument>
@@ -127,6 +156,26 @@ abstract class DataNormalizationOperation<T extends PathArgument> implements Ide
             return register(potential);
         }
 
+        @Override
+        final DataNormalizationOperation<?> enterChild(final QName child, final SchemaInferenceStack stack)
+                throws DataNormalizationException {
+            return pushToStack(getChild(child), stack);
+        }
+
+        @Override
+        final DataNormalizationOperation<?> enterChild(final PathArgument child, final SchemaInferenceStack stack)
+                throws DataNormalizationException {
+            return pushToStack(getChild(child), stack);
+        }
+
+        private static DataNormalizationOperation<?> pushToStack(final DataNormalizationOperation<?> child,
+                final SchemaInferenceStack stack) {
+            if (child != null) {
+                child.pushToStack(stack);
+            }
+            return child;
+        }
+
         private DataNormalizationOperation<?> fromLocalSchema(final PathArgument child)
                 throws DataNormalizationException {
             if (child instanceof AugmentationIdentifier) {
@@ -174,6 +223,11 @@ abstract class DataNormalizationOperation<T extends PathArgument> implements Ide
         ListItemNormalization(final NodeIdentifierWithPredicates identifier, final ListSchemaNode schema) {
             super(identifier, schema);
         }
+
+        @Override
+        protected void pushToStack(final SchemaInferenceStack stack) {
+            // No-op
+        }
     }
 
     private static final class UnkeyedListItemNormalization
@@ -181,6 +235,11 @@ abstract class DataNormalizationOperation<T extends PathArgument> implements Ide
         UnkeyedListItemNormalization(final ListSchemaNode schema) {
             super(new NodeIdentifier(schema.getQName()), schema);
         }
+
+        @Override
+        protected void pushToStack(final SchemaInferenceStack stack) {
+            // No-op
+        }
     }
 
     private static final class ContainerNormalization extends DataContainerNormalizationOperation<NodeIdentifier> {
@@ -200,7 +259,26 @@ abstract class DataNormalizationOperation<T extends PathArgument> implements Ide
         }
     }
 
-    private static final class LeafListMixinNormalization extends MixinNormalizationOp<NodeIdentifier> {
+    private abstract static class ListLikeNormalizationOp<T extends PathArgument> extends MixinNormalizationOp<T> {
+        ListLikeNormalizationOp(final T identifier) {
+            super(identifier);
+        }
+
+        @Override
+        protected final DataNormalizationOperation<?> enterChild(final QName child, final SchemaInferenceStack stack)
+                throws DataNormalizationException {
+            // Stack is already pointing to the corresponding statement, now we are just working with the child
+            return getChild(child);
+        }
+
+        @Override
+        protected final DataNormalizationOperation<?> enterChild(final PathArgument child,
+                final SchemaInferenceStack stack) throws DataNormalizationException {
+            return getChild(child);
+        }
+    }
+
+    private static final class LeafListMixinNormalization extends ListLikeNormalizationOp<NodeIdentifier> {
         private final DataNormalizationOperation<?> innerOp;
 
         LeafListMixinNormalization(final LeafListSchemaNode potential) {
@@ -265,6 +343,11 @@ abstract class DataNormalizationOperation<T extends PathArgument> implements Ide
             return getIdentifier().getPossibleChildNames();
         }
 
+        @Override
+        void pushToStack(final SchemaInferenceStack stack) {
+            // No-op
+        }
+
         private static AugmentationIdentifier augmentationIdentifierFrom(final AugmentationSchemaNode augmentation) {
             final ImmutableSet.Builder<QName> potentialChildren = ImmutableSet.builder();
             for (final DataSchemaNode child : augmentation.getChildNodes()) {
@@ -274,7 +357,7 @@ abstract class DataNormalizationOperation<T extends PathArgument> implements Ide
         }
     }
 
-    private static final class MapMixinNormalization extends MixinNormalizationOp<NodeIdentifier> {
+    private static final class MapMixinNormalization extends ListLikeNormalizationOp<NodeIdentifier> {
         private final ListItemNormalization innerNode;
 
         MapMixinNormalization(final ListSchemaNode list) {
@@ -299,7 +382,7 @@ abstract class DataNormalizationOperation<T extends PathArgument> implements Ide
         }
     }
 
-    private static final class UnkeyedListMixinNormalization extends MixinNormalizationOp<NodeIdentifier> {
+    private static final class UnkeyedListMixinNormalization extends ListLikeNormalizationOp<NodeIdentifier> {
         private final UnkeyedListItemNormalization innerNode;
 
         UnkeyedListMixinNormalization(final ListSchemaNode list) {
@@ -327,9 +410,11 @@ abstract class DataNormalizationOperation<T extends PathArgument> implements Ide
     private static final class ChoiceNodeNormalization extends MixinNormalizationOp<NodeIdentifier> {
         private final ImmutableMap<QName, DataNormalizationOperation<?>> byQName;
         private final ImmutableMap<PathArgument, DataNormalizationOperation<?>> byArg;
+        private final ImmutableMap<DataNormalizationOperation<?>, QName> childToCase;
 
         ChoiceNodeNormalization(final ChoiceSchemaNode schema) {
             super(new NodeIdentifier(schema.getQName()));
+            ImmutableMap.Builder<DataNormalizationOperation<?>, QName> childToCaseBuilder = ImmutableMap.builder();
             final ImmutableMap.Builder<QName, DataNormalizationOperation<?>> byQNameBuilder = ImmutableMap.builder();
             final ImmutableMap.Builder<PathArgument, DataNormalizationOperation<?>> byArgBuilder =
                     ImmutableMap.builder();
@@ -338,11 +423,13 @@ abstract class DataNormalizationOperation<T extends PathArgument> implements Ide
                 for (final DataSchemaNode cazeChild : caze.getChildNodes()) {
                     final DataNormalizationOperation<?> childOp = fromDataSchemaNode(cazeChild);
                     byArgBuilder.put(childOp.getIdentifier(), childOp);
+                    childToCaseBuilder.put(childOp, caze.getQName());
                     for (final QName qname : childOp.getQNameIdentifiers()) {
                         byQNameBuilder.put(qname, childOp);
                     }
                 }
             }
+            childToCase = childToCaseBuilder.build();
             byQName = byQNameBuilder.build();
             byArg = byArgBuilder.build();
         }
@@ -361,6 +448,32 @@ abstract class DataNormalizationOperation<T extends PathArgument> implements Ide
         Set<QName> getQNameIdentifiers() {
             return byQName.keySet();
         }
+
+        @Override
+        DataNormalizationOperation<?> enterChild(final QName child, final SchemaInferenceStack stack) {
+            return pushToStack(getChild(child), stack);
+        }
+
+        @Override
+        DataNormalizationOperation<?> enterChild(final PathArgument child, final SchemaInferenceStack stack) {
+            return pushToStack(getChild(child), stack);
+        }
+
+        @Override
+        void pushToStack(final SchemaInferenceStack stack) {
+            stack.enterChoice(getIdentifier().getNodeType());
+        }
+
+        private DataNormalizationOperation<?> pushToStack(final DataNormalizationOperation<?> child,
+                final SchemaInferenceStack stack) {
+            if (child != null) {
+                final var caseName = verifyNotNull(childToCase.get(child), "No case statement for %s in %s", child,
+                    this);
+                stack.enterSchemaTree(caseName);
+                child.pushToStack(stack);
+            }
+            return child;
+        }
     }
 
     private static final class AnyxmlNormalization extends SimpleTypeNormalization<NodeIdentifier> {