Defer mutatesEffectiveCtxPath() hookOnto() 56/98856/1
authorRobert Varga <robert.varga@pantheon.tech>
Tue, 23 Nov 2021 12:45:27 +0000 (13:45 +0100)
committerRobert Varga <robert.varga@pantheon.tech>
Mon, 6 Dec 2021 11:10:03 +0000 (12:10 +0100)
When we are resolving statements along schema tree axis we may end up
hitting a statement which is already resolved as unsupported. In that
case we would end up derefencing a known-null action. Defer
initialization until the action is set.

JIRA: YANGTOOLS-1370
Change-Id: I5dbc7c047cbbb78b015c4d09c8b271bb218fef4b
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
(cherry picked from commit 02d8511d8b1e4277a7069d1cf105269d2305f432)

yang/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/ModifierImpl.java

index 5edde2ffd80a3b391b6c6d86331cce5b11fb27a7..3a9eafa9b74dac598a77640ec004a8c3596267cb 100644 (file)
@@ -16,8 +16,10 @@ import static org.opendaylight.yangtools.yang.parser.spi.meta.ModelProcessingPha
 
 import com.google.common.base.MoreObjects;
 import com.google.common.base.MoreObjects.ToStringHelper;
+import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.Iterator;
+import java.util.List;
 import java.util.Set;
 import java.util.function.Function;
 import org.eclipse.jdt.annotation.NonNull;
@@ -39,13 +41,13 @@ import org.slf4j.LoggerFactory;
 final class ModifierImpl implements ModelActionBuilder {
     private static final Logger LOG = LoggerFactory.getLogger(ModifierImpl.class);
 
-    private final InferenceContext ctx = new InferenceContext() { };
-
     private final Set<AbstractPrerequisite<?>> unsatisfied = new HashSet<>(1);
     private final Set<AbstractPrerequisite<?>> mutations = new HashSet<>(1);
+    private final InferenceContext ctx = new InferenceContext() { };
 
+    private List<Runnable> bootstraps;
     private InferenceAction action;
-    private boolean actionApplied = false;
+    private boolean actionApplied;
 
     private <D> AbstractPrerequisite<D> addReq(final AbstractPrerequisite<D> prereq) {
         LOG.trace("Modifier {} adding prerequisite {}", this, prereq);
@@ -250,7 +252,10 @@ final class ModifierImpl implements ModelActionBuilder {
         addReq(ret);
         addMutation(ret);
 
-        ret.hookOnto(context, namespace);
+        if (bootstraps == null) {
+            bootstraps = new ArrayList<>(1);
+        }
+        bootstraps.add(() -> ret.hookOnto(context, namespace));
         return ret;
     }
 
@@ -259,6 +264,10 @@ final class ModifierImpl implements ModelActionBuilder {
     public void apply(final InferenceAction action) {
         checkState(this.action == null, "Action already defined to %s", this.action);
         this.action = requireNonNull(action);
+        if (bootstraps != null) {
+            bootstraps.forEach(Runnable::run);
+            bootstraps = null;
+        }
     }
 
     private abstract class AbstractPrerequisite<T> implements Prerequisite<T> {