Add DataSchemaContextNode/SchemaInferenceStack integration
[yangtools.git] / data / yang-data-util / src / main / java / org / opendaylight / yangtools / yang / data / util / DataContainerContextNode.java
index 51aa4e284d424e260a75ce9e96fc3d27398d24de..5059deae83d794ade47c55db8027caaec7bddafb 100644 (file)
@@ -7,27 +7,27 @@
  */
 package org.opendaylight.yangtools.yang.data.util;
 
-import java.util.Map;
+import static java.util.Objects.requireNonNull;
+
 import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack;
 
-class DataContainerContextNode<T extends PathArgument> extends
-        AbstractInteriorContextNode<T> {
-
-    private final DataNodeContainer schema;
-    private final Map<QName, DataSchemaContextNode<?>> byQName;
-    private final Map<PathArgument, DataSchemaContextNode<?>> byArg;
+abstract class DataContainerContextNode<T extends PathArgument> extends AbstractInteriorContextNode<T> {
+    private final ConcurrentMap<PathArgument, DataSchemaContextNode<?>> byArg = new ConcurrentHashMap<>();
+    private final ConcurrentMap<QName, DataSchemaContextNode<?>> byQName = new ConcurrentHashMap<>();
+    private final DataNodeContainer container;
 
-    protected DataContainerContextNode(final T identifier, final DataNodeContainer schema,
-            final DataSchemaNode node) {
-        super(identifier, node);
-        this.schema = schema;
-        this.byArg = new ConcurrentHashMap<>();
-        this.byQName = new ConcurrentHashMap<>();
+    DataContainerContextNode(final T identifier, final DataNodeContainer container, final DataSchemaNode schema) {
+        super(identifier, schema);
+        this.container = requireNonNull(container);
     }
 
     @Override
@@ -46,24 +46,44 @@ class DataContainerContextNode<T extends PathArgument> extends
         if (potential != null) {
             return potential;
         }
-        potential = fromLocalSchemaAndQName(schema, child);
+        potential = fromLocalSchemaAndQName(container, child);
         return register(potential);
     }
 
+    @Override
+    protected final DataSchemaContextNode<?> enterChild(final QName child, final SchemaInferenceStack stack) {
+        return pushToStack(getChild(child), stack);
+    }
+
+
+    @Override
+    protected final DataSchemaContextNode<?> enterChild(final PathArgument child, final SchemaInferenceStack stack) {
+        return pushToStack(getChild(child), stack);
+    }
+
+    private static @Nullable DataSchemaContextNode<?> pushToStack(final @Nullable DataSchemaContextNode<?> child,
+            final @NonNull SchemaInferenceStack stack) {
+        if (child != null) {
+            child.pushToStack(stack);
+        }
+        return child;
+    }
+
     private DataSchemaContextNode<?> fromLocalSchema(final PathArgument child) {
         if (child instanceof AugmentationIdentifier) {
-            return fromSchemaAndQNameChecked(schema, ((AugmentationIdentifier) child).getPossibleChildNames()
+            return fromSchemaAndQNameChecked(container, ((AugmentationIdentifier) child).getPossibleChildNames()
                     .iterator().next());
         }
-        return fromSchemaAndQNameChecked(schema, child.getNodeType());
+        return fromSchemaAndQNameChecked(container, child.getNodeType());
     }
 
-    protected DataSchemaContextNode<?> fromLocalSchemaAndQName(final DataNodeContainer schema2, final QName child) {
-        return fromSchemaAndQNameChecked(schema2, child);
+    protected DataSchemaContextNode<?> fromLocalSchemaAndQName(final DataNodeContainer schema, final QName child) {
+        return fromSchemaAndQNameChecked(schema, child);
     }
 
     private DataSchemaContextNode<?> register(final DataSchemaContextNode<?> potential) {
         if (potential != null) {
+            // FIXME: use putIfAbsent() to make sure we do not perform accidental overrwrites
             byArg.put(potential.getIdentifier(), potential);
             for (QName qname : potential.getQNameIdentifiers()) {
                 byQName.put(qname, potential);
@@ -71,5 +91,4 @@ class DataContainerContextNode<T extends PathArgument> extends
         }
         return potential;
     }
-
 }