Bug 4456 - StackOverflowError on recursive extension definition
[yangtools.git] / yang / yang-parser-impl / src / main / java / org / opendaylight / yangtools / yang / parser / stmt / rfc6020 / effective / ExtensionEffectiveStatementImpl.java
index efb543a82392dfcd397cffa66bf6df0da89ecc46..be762942462ba132a44667ef6a15061bc09ff238 100644 (file)
@@ -9,6 +9,7 @@ package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective;
 
 import com.google.common.collect.ImmutableList;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.List;
 import java.util.Objects;
 import org.opendaylight.yangtools.yang.common.QName;
@@ -25,25 +26,15 @@ public class ExtensionEffectiveStatementImpl extends AbstractEffectiveDocumented
     private final String argument;
     private final SchemaPath schemaPath;
 
-    private final List<UnknownSchemaNode> unknownNodes;
+    private List<UnknownSchemaNode> unknownNodes;
     private final boolean yin;
 
     public ExtensionEffectiveStatementImpl(
             final StmtContext<QName, ExtensionStatement, EffectiveStatement<QName, ExtensionStatement>> ctx) {
-        super(ctx);
+        super(ctx, false);
         this.qname = ctx.getStatementArgument();
         this.schemaPath = ctx.getSchemaPath().get();
 
-        // initSubstatementCollections
-        List<UnknownSchemaNode> unknownNodesInit = new ArrayList<>();
-        for (EffectiveStatement<?, ?> effectiveStatement : effectiveSubstatements()) {
-            if (effectiveStatement instanceof UnknownSchemaNode) {
-                UnknownSchemaNode unknownNode = (UnknownSchemaNode) effectiveStatement;
-                unknownNodesInit.add(unknownNode);
-            }
-        }
-        this.unknownNodes = ImmutableList.copyOf(unknownNodesInit);
-
         // initFields
         ArgumentEffectiveStatementImpl argumentSubstatement = firstEffective(ArgumentEffectiveStatementImpl.class);
         if (argumentSubstatement != null) {
@@ -62,6 +53,21 @@ public class ExtensionEffectiveStatementImpl extends AbstractEffectiveDocumented
         }
     }
 
+    void initUnknownSchemaNodes() {
+        if (unknownNodes != null) {
+            return;
+        }
+
+        Collection<EffectiveStatement<?, ?>> buildedUnknownNodes = getOmittedUnknownSubstatements();
+        List<UnknownSchemaNode> unknownNodesInit = new ArrayList<>();
+        for (EffectiveStatement<?, ?> unknownNode : buildedUnknownNodes) {
+            if (unknownNode instanceof UnknownSchemaNode) {
+                unknownNodesInit.add((UnknownSchemaNode) unknownNode);
+            }
+        }
+        this.unknownNodes = ImmutableList.copyOf(unknownNodesInit);
+    }
+
     @Override
     public QName getQName() {
         return qname;
@@ -74,6 +80,9 @@ public class ExtensionEffectiveStatementImpl extends AbstractEffectiveDocumented
 
     @Override
     public List<UnknownSchemaNode> getUnknownSchemaNodes() {
+        if(unknownNodes == null) {
+            initUnknownSchemaNodes();
+        }
         return unknownNodes;
     }