BUG-7052: reduce StatementContextBase proliferation even more
[yangtools.git] / yang / yang-parser-impl / src / main / java / org / opendaylight / yangtools / yang / parser / stmt / reactor / SubstatementContext.java
index d2e5c733d3bf63c44bb213db9afc5d895746ce58..2710f0802ad025bb3fc26f1f233b8f40487acc7a 100644 (file)
@@ -67,6 +67,8 @@ final class SubstatementContext<A, D extends DeclaredStatement<A>, E extends Eff
      */
     private boolean haveConfiguration;
     private boolean configuration;
+    private boolean wasCheckedIfInYangDataExtensionBody;
+    private boolean isInYangDataExtensionBody;
 
     private volatile SchemaPath schemaPath;
 
@@ -132,7 +134,7 @@ final class SubstatementContext<A, D extends DeclaredStatement<A>, E extends Eff
     }
 
     @Override
-    public StatementContextBase<?, ?, ?> createCopy(final StatementContextBase<?, ?, ?> newParent,
+    public StatementContextBase<A, D, E> createCopy(final StatementContextBase<?, ?, ?> newParent,
             final CopyType typeOfCopy) {
         return createCopy(null, newParent, typeOfCopy);
     }
@@ -161,28 +163,27 @@ final class SubstatementContext<A, D extends DeclaredStatement<A>, E extends Eff
 
     private void copyStatements(final SubstatementContext<A, D, E> original, final QNameModule newQNameModule,
             final CopyType typeOfCopy) {
-        final Collection<StatementContextBase<?, ?, ?>> declared = original.declaredSubstatements();
-        final Collection<StatementContextBase<?, ?, ?>> effective = original.effectiveSubstatements();
-        final Collection<StatementContextBase<?, ?, ?>> buffer = new ArrayList<>(declared.size() + effective.size());
+        final Collection<? extends Mutable<?, ?, ?>> declared = original.mutableDeclaredSubstatements();
+        final Collection<? extends Mutable<?, ?, ?>> effective = original.mutableEffectiveSubstatements();
+        final Collection<Mutable<?, ?, ?>> buffer = new ArrayList<>(declared.size() + effective.size());
 
-        for (final StatementContextBase<?, ?, ?> stmtContext : declared) {
-            if (StmtContextUtils.areFeaturesSupported(stmtContext)) {
+        for (final Mutable<?, ?, ?> stmtContext : declared) {
+            if (stmtContext.isSupportedByFeatures()) {
                 copySubstatement(stmtContext, newQNameModule, typeOfCopy, buffer);
             }
         }
 
-        for (final StatementContextBase<?, ?, ?> stmtContext : effective) {
+        for (final Mutable<?, ?, ?> stmtContext : effective) {
             copySubstatement(stmtContext, newQNameModule, typeOfCopy, buffer);
         }
 
         addEffectiveSubstatements(buffer);
     }
 
-    private void copySubstatement(final StatementContextBase<?, ?, ?> stmtContext,
-            final QNameModule newQNameModule, final CopyType typeOfCopy,
-            final Collection<StatementContextBase<?, ?, ?>> buffer) {
+    private void copySubstatement(final Mutable<?, ?, ?> stmtContext, final QNameModule newQNameModule,
+            final CopyType typeOfCopy, final Collection<Mutable<?, ?, ?>> buffer) {
         if (needToCopyByUses(stmtContext)) {
-            final StatementContextBase<?, ?, ?> copy = stmtContext.createCopy(newQNameModule, this, typeOfCopy);
+            final Mutable<?, ?, ?> copy = stmtContext.createCopy(newQNameModule, this, typeOfCopy);
             LOG.debug("Copying substatement {} for {} as", stmtContext, this, copy);
             buffer.add(copy);
         } else if (isReusedByUses(stmtContext)) {
@@ -253,7 +254,7 @@ final class SubstatementContext<A, D extends DeclaredStatement<A>, E extends Eff
         }
         if (argument instanceof String) {
             // FIXME: This may yield illegal argument exceptions
-            final StatementContextBase<?, ?, ?> originalCtx = getOriginalCtx();
+            final StmtContext<?, ?, ?> originalCtx = getOriginalCtx();
             final QName qname = originalCtx != null ? Utils.qNameFromArgument(originalCtx, (String) argument) : Utils
                     .qNameFromArgument(this, (String) argument);
             return parentPath.createChild(qname);
@@ -295,6 +296,13 @@ final class SubstatementContext<A, D extends DeclaredStatement<A>, E extends Eff
 
     @Override
     public boolean isConfiguration() {
+        // if this statement is within a 'yang-data' extension body, config substatements are ignored as if
+        // they were not declared. As 'yang-data' is always a top-level node, all configs that are within it are
+        // automatically true
+        if (isInYangDataExtensionBody()) {
+            return true;
+        }
+
         if (haveConfiguration) {
             return configuration;
         }
@@ -321,6 +329,23 @@ final class SubstatementContext<A, D extends DeclaredStatement<A>, E extends Eff
         return isConfig;
     }
 
+    @Override
+    public boolean isInYangDataExtensionBody() {
+        if (wasCheckedIfInYangDataExtensionBody) {
+            return isInYangDataExtensionBody;
+        }
+
+        final boolean parentIsInYangDataExtensionBody = parent.isInYangDataExtensionBody();
+        if (parentIsInYangDataExtensionBody) {
+            isInYangDataExtensionBody = parentIsInYangDataExtensionBody;
+        } else {
+            isInYangDataExtensionBody = StmtContextUtils.hasYangDataExtensionParent(this);
+        }
+
+        wasCheckedIfInYangDataExtensionBody = true;
+        return isInYangDataExtensionBody;
+    }
+
     @Override
     public boolean isEnabledSemanticVersioning() {
         return parent.isEnabledSemanticVersioning();