Make BitsTypeDefinition.Bit only a DocumentedNode.WithStatus
[yangtools.git] / yang / yang-parser-rfc7950 / src / main / java / org / opendaylight / yangtools / yang / parser / rfc7950 / stmt / AbstractEffectiveDocumentedNode.java
index 5f09391c7bd802dafc9fce84c74d4b97885f0347..0d217c24888eb2636b8f872333dee56a8b73997d 100644 (file)
@@ -7,18 +7,40 @@
  */
 package org.opendaylight.yangtools.yang.parser.rfc7950.stmt;
 
+import com.google.common.collect.ImmutableList;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
 import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.yangtools.yang.model.api.DocumentedNode;
 import org.opendaylight.yangtools.yang.model.api.Status;
+import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.StatusEffectiveStatement;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
 
 // FIXME: 5.0.0: rename to AbstractEffectiveDocumentedNodeWithStatus
 public abstract class AbstractEffectiveDocumentedNode<A, D extends DeclaredStatement<A>>
         extends AbstractEffectiveDocumentedNodeWithoutStatus<A, D> implements DocumentedNode.WithStatus {
+    private static final VarHandle UNKNOWN_NODES;
+
+    static {
+        try {
+            UNKNOWN_NODES = MethodHandles.lookup().findVarHandle(AbstractEffectiveDocumentedNode.class,
+                "unknownNodes", ImmutableList.class);
+        } catch (NoSuchFieldException | IllegalAccessException e) {
+            throw new ExceptionInInitializerError(e);
+        }
+    }
+
     private final @NonNull Status status;
 
+    @SuppressWarnings("unused")
+    private volatile ImmutableList<UnknownSchemaNode> unknownNodes;
+
     /**
      * Constructor.
      *
@@ -34,4 +56,25 @@ public abstract class AbstractEffectiveDocumentedNode<A, D extends DeclaredState
     public final Status getStatus() {
         return status;
     }
+
+    @Override
+    public final Collection<? extends UnknownSchemaNode> getUnknownSchemaNodes() {
+        final ImmutableList<UnknownSchemaNode> existing =
+                (ImmutableList<UnknownSchemaNode>) UNKNOWN_NODES.getAcquire(this);
+        return existing != null ? existing : loadUnknownSchemaNodes();
+    }
+
+    @SuppressWarnings("unchecked")
+    private @NonNull ImmutableList<UnknownSchemaNode> loadUnknownSchemaNodes() {
+        final List<UnknownSchemaNode> init = new ArrayList<>();
+        for (EffectiveStatement<?, ?> stmt : effectiveSubstatements()) {
+            if (stmt instanceof UnknownSchemaNode) {
+                init.add((UnknownSchemaNode) stmt);
+            }
+        }
+
+        final ImmutableList<UnknownSchemaNode> computed = ImmutableList.copyOf(init);
+        final Object witness = UNKNOWN_NODES.compareAndExchangeRelease(this, null, computed);
+        return witness == null ? computed : (ImmutableList<UnknownSchemaNode>) witness;
+    }
 }