Improve OriginalLink safety
[mdsal.git] / binding / mdsal-binding-generator / src / main / java / org / opendaylight / mdsal / binding / generator / impl / reactor / AbstractExplicitGenerator.java
index 69a2f217e51e242d9408940958e1f232935ec471..10cac0c71c5d2b669934ae1e86689a40bb15acb0 100644 (file)
@@ -50,11 +50,11 @@ public abstract class AbstractExplicitGenerator<T extends EffectiveStatement<?,
      *   <li>a generator which is one step closer to the original definition</li>
      * </ul>
      */
-    private AbstractExplicitGenerator<?> prev;
+    private AbstractExplicitGenerator<T> prev;
     /**
      * Field holding the original incarnation, i.e. the terminal node along {@link #prev} links.
      */
-    private AbstractExplicitGenerator<?> orig;
+    private AbstractExplicitGenerator<T> orig;
 
     AbstractExplicitGenerator(final T statement) {
         this.statement = requireNonNull(statement);
@@ -85,15 +85,14 @@ public abstract class AbstractExplicitGenerator<T extends EffectiveStatement<?,
     }
 
     /**
-     * Attempt to link the generator corresponding to the original definition for this generator's statements as well as
-     * to all child generators.
+     * Attempt to link the generator corresponding to the original definition for this generator.
      *
-     * @return Number of generators that remain unlinked.
+     * @return {@code true} if this generator is linked
      */
-    long linkOriginalGenerator() {
+    final boolean linkOriginalGenerator() {
         if (orig != null) {
             // Original already linked
-            return 0;
+            return true;
         }
 
         if (prev == null) {
@@ -102,27 +101,32 @@ public abstract class AbstractExplicitGenerator<T extends EffectiveStatement<?,
             if (!isAddedByUses() && !isAugmenting()) {
                 orig = prev = this;
                 LOG.trace("Linked {} to self", this);
-                return 0;
+                return true;
+            }
+
+            final var link = getParent().<T>originalChild(getQName());
+            if (link == null) {
+                LOG.trace("Cannot link {} yet", this);
+                return false;
             }
 
-            final var link = getParent().getOriginalChild(getQName());
             prev = link.previous();
             orig = link.original();
             if (orig != null) {
                 LOG.trace("Linked {} to {} original {}", this, prev, orig);
-                return 0;
+                return true;
             }
 
             LOG.trace("Linked {} to intermediate {}", this, prev);
-            return 1;
+            return false;
         }
 
         orig = prev.originalLink().original();
         if (orig != null) {
             LOG.trace("Linked {} to original {}", this, orig);
-            return 0;
+            return true;
         }
-        return 1;
+        return false;
     }
 
     /**
@@ -130,7 +134,7 @@ public abstract class AbstractExplicitGenerator<T extends EffectiveStatement<?,
      *
      * @return Previous incarnation or {@code null}
      */
-    final @Nullable AbstractExplicitGenerator<?> previous() {
+    final @Nullable AbstractExplicitGenerator<T> previous() {
         final var local = verifyNotNull(prev, "Generator %s does not have linkage to previous instance resolved", this);
         return local == this ? null : local;
     }
@@ -140,16 +144,20 @@ public abstract class AbstractExplicitGenerator<T extends EffectiveStatement<?,
      *
      * @return Original incarnation of this generator
      */
-    @NonNull AbstractExplicitGenerator<?> getOriginal() {
+    @NonNull AbstractExplicitGenerator<T> getOriginal() {
         return verifyNotNull(orig, "Generator %s does not have linkage to original instance resolved", this);
     }
 
+    @Nullable AbstractExplicitGenerator<T> tryOriginal() {
+        return orig;
+    }
+
     /**
      * Return the link towards the original generator.
      *
      * @return Link towards the original generator.
      */
-    final @NonNull OriginalLink originalLink() {
+    final @NonNull OriginalLink<T> originalLink() {
         final var local = prev;
         if (local == null) {
             return OriginalLink.partial(this);
@@ -161,6 +169,10 @@ public abstract class AbstractExplicitGenerator<T extends EffectiveStatement<?,
     }
 
     @Nullable AbstractExplicitGenerator<?> findSchemaTreeGenerator(final QName qname) {
+        return findLocalSchemaTreeGenerator(qname);
+    }
+
+    final @Nullable AbstractExplicitGenerator<?> findLocalSchemaTreeGenerator(final QName qname) {
         for (Generator child : this) {
             if (child instanceof AbstractExplicitGenerator) {
                 final AbstractExplicitGenerator<?> gen = (AbstractExplicitGenerator<?>) child;