Refactor ListEffectiveStatementImpl
[yangtools.git] / yang / yang-parser-rfc7950 / src / main / java / org / opendaylight / yangtools / yang / parser / rfc7950 / stmt / AbstractSchemaEffectiveDocumentedNode.java
index b5a9757ea953b7e936a58c61dfdb4b8df70fdbdd..79ae09fee62edd01e50e645716b1b21f0002609a 100644 (file)
@@ -14,6 +14,7 @@ import com.google.common.annotations.Beta;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
 import java.lang.invoke.VarHandle;
+import java.util.Collection;
 import java.util.LinkedHashMap;
 import java.util.Map;
 import java.util.Optional;
@@ -22,6 +23,7 @@ import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
 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.meta.IdentifierNamespace;
 import org.opendaylight.yangtools.yang.model.api.stmt.CaseEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.ChoiceEffectiveStatement;
@@ -53,37 +55,16 @@ public abstract class AbstractSchemaEffectiveDocumentedNode<A, D extends Declare
         // EffectiveStatements and SchemaNode interfaces -- which do not overlap completely where child lookups are
         // concerned. This ensures that we have SchemaTree index available for use with child lookups.
         if (this instanceof SchemaTreeAwareEffectiveStatement || this instanceof DataNodeContainer) {
-            final StatementSourceReference ref = ctx.getStatementSourceReference();
-            final Map<QName, SchemaTreeEffectiveStatement<?>> schemaChildren = new LinkedHashMap<>();
-            streamEffectiveSubstatements(SchemaTreeEffectiveStatement.class).forEach(child -> {
-                putChild(schemaChildren, child, ref, "schema");
-            });
-            schemaTreeNamespace = ImmutableMap.copyOf(schemaChildren);
-
-            if (this instanceof DataTreeAwareEffectiveStatement && !schemaTreeNamespace.isEmpty()) {
-                final Map<QName, DataTreeEffectiveStatement<?>> dataChildren = new LinkedHashMap<>();
-                boolean sameAsSchema = true;
-
-                for (SchemaTreeEffectiveStatement<?> child : schemaTreeNamespace.values()) {
-                    if (child instanceof DataTreeEffectiveStatement) {
-                        putChild(dataChildren, (DataTreeEffectiveStatement<?>) child, ref, "data");
-                    } else {
-                        sameAsSchema = false;
-                        putChoiceDataChildren(dataChildren, ref, child);
-                    }
-                }
-
-                // This is a mighty hack to lower memory usage: if we consumed all schema tree children as data nodes,
-                // the two maps are equal and hence we can share the instance.
-                dataTreeNamespace = sameAsSchema ? (ImmutableMap) schemaTreeNamespace
-                        : ImmutableMap.copyOf(dataChildren);
-            } else {
-                dataTreeNamespace = ImmutableMap.of();
-            }
+            schemaTreeNamespace = createSchemaTreeNamespace(ctx.getStatementSourceReference(),
+                effectiveSubstatements());
         } else {
-            dataTreeNamespace = ImmutableMap.of();
             schemaTreeNamespace = ImmutableMap.of();
         }
+        if (this instanceof DataTreeAwareEffectiveStatement && !schemaTreeNamespace.isEmpty()) {
+            dataTreeNamespace = createDataTreeNamespace(ctx.getStatementSourceReference(), schemaTreeNamespace);
+        } else {
+            dataTreeNamespace = ImmutableMap.of();
+        }
     }
 
     @Override
@@ -116,6 +97,34 @@ public abstract class AbstractSchemaEffectiveDocumentedNode<A, D extends Declare
         return child instanceof DataSchemaNode ? Optional.of((DataSchemaNode) child) : Optional.empty();
     }
 
+    static @NonNull ImmutableMap<QName, SchemaTreeEffectiveStatement<?>> createSchemaTreeNamespace(
+            final StatementSourceReference ref, final Collection<? extends EffectiveStatement<?, ?>> substatements) {
+        final Map<QName, SchemaTreeEffectiveStatement<?>> schemaChildren = new LinkedHashMap<>();
+        substatements.stream().filter(SchemaTreeEffectiveStatement.class::isInstance)
+            .forEach(child -> putChild(schemaChildren, (SchemaTreeEffectiveStatement) child, ref, "schema"));
+        return ImmutableMap.copyOf(schemaChildren);
+    }
+
+    static @NonNull ImmutableMap<QName, DataTreeEffectiveStatement<?>> createDataTreeNamespace(
+            final StatementSourceReference ref,
+            final ImmutableMap<QName, SchemaTreeEffectiveStatement<?>> schemaTreeNamespace) {
+        final Map<QName, DataTreeEffectiveStatement<?>> dataChildren = new LinkedHashMap<>();
+        boolean sameAsSchema = true;
+
+        for (SchemaTreeEffectiveStatement<?> child : schemaTreeNamespace.values()) {
+            if (child instanceof DataTreeEffectiveStatement) {
+                putChild(dataChildren, (DataTreeEffectiveStatement<?>) child, ref, "data");
+            } else {
+                sameAsSchema = false;
+                putChoiceDataChildren(dataChildren, ref, child);
+            }
+        }
+
+        // This is a mighty hack to lower memory usage: if we consumed all schema tree children as data nodes,
+        // the two maps are equal and hence we can share the instance.
+        return sameAsSchema ? (ImmutableMap) schemaTreeNamespace : ImmutableMap.copyOf(dataChildren);
+    }
+
     @SuppressWarnings("unchecked")
     private <T> @NonNull ImmutableSet<T> loadSet(final VarHandle vh, final @NonNull Class<T> clazz) {
         final ImmutableSet<T> computed = ImmutableSet.copyOf(allSubstatementsOfType(clazz));