Refactor InferenceAction
[yangtools.git] / yang / yang-parser-impl / src / main / java / org / opendaylight / yangtools / yang / parser / spi / meta / StmtContextUtils.java
index ad1c7e78d2e6b60b2f640c46ca548c6f2844dacf..ad3b07d84e162c7539fa40d83957b6397f440ca8 100644 (file)
@@ -31,9 +31,8 @@ import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier;
 import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
 import org.opendaylight.yangtools.yang.parser.spi.source.SupportedFeaturesNamespace;
 import org.opendaylight.yangtools.yang.parser.spi.source.SupportedFeaturesNamespace.SupportedFeatures;
-import org.opendaylight.yangtools.yang.parser.stmt.reactor.RootStatementContext;
-import org.opendaylight.yangtools.yang.parser.stmt.reactor.StatementContextBase;
 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.UnknownStatementImpl;
+import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.YangDataStatementImpl;
 
 public final class StmtContextUtils {
     public static final Splitter LIST_KEY_SPLITTER = Splitter.on(' ').omitEmptyStrings().trimResults();
@@ -205,6 +204,16 @@ public final class StmtContextUtils {
         return false;
     }
 
+    /**
+     * Checks if the statement context has a 'yang-data' extension node as its parent.
+     *
+     * @param stmtCtx statement context to be checked
+     * @return true if the parent node is a 'yang-data' node, otherwise false
+     */
+    public static boolean hasYangDataExtensionParent(final StmtContext<?, ?, ?> stmtCtx) {
+        return producesDeclared(stmtCtx.getParentContext(), YangDataStatementImpl.class);
+    }
+
     public static boolean isUnknownStatement(final StmtContext<?, ?, ?> stmtCtx) {
         return producesDeclared(stmtCtx, UnknownStatementImpl.class);
     }
@@ -262,8 +271,12 @@ public final class StmtContextUtils {
             final Set<QName> supportedFeatures) {
         boolean isSupported = false;
         boolean containsIfFeature = false;
-        for (final StatementContextBase<?, ?, ?> stmt : stmtContext.declaredSubstatements()) {
+        for (final StmtContext<?, ?, ?> stmt : stmtContext.declaredSubstatements()) {
             if (YangStmtMapping.IF_FEATURE.equals(stmt.getPublicDefinition())) {
+                if (stmtContext.isInYangDataExtensionBody()) {
+                    break;
+                }
+
                 containsIfFeature = true;
                 if (((Predicate<Set<QName>>) stmt.getStatementArgument()).test(supportedFeatures)) {
                     isSupported = true;
@@ -284,7 +297,7 @@ public final class StmtContextUtils {
      *            statement context
      * @return true if it is a presence container
      */
-    public static boolean isPresenceContainer(final StatementContextBase<?, ?, ?> stmtCtx) {
+    public static boolean isPresenceContainer(final StmtContext<?, ?, ?> stmtCtx) {
         return stmtCtx.getPublicDefinition() == YangStmtMapping.CONTAINER && containsPresenceSubStmt(stmtCtx);
     }
 
@@ -295,27 +308,24 @@ public final class StmtContextUtils {
      *            statement context
      * @return true if it is a non-presence container
      */
-    public static boolean isNonPresenceContainer(final StatementContextBase<?, ?, ?> stmtCtx) {
+    public static boolean isNonPresenceContainer(final StmtContext<?, ?, ?> stmtCtx) {
         return stmtCtx.getPublicDefinition() == YangStmtMapping.CONTAINER && !containsPresenceSubStmt(stmtCtx);
     }
 
-    private static boolean containsPresenceSubStmt(final StatementContextBase<?, ?, ?> stmtCtx) {
+    private static boolean containsPresenceSubStmt(final StmtContext<?, ?, ?> stmtCtx) {
         return findFirstSubstatement(stmtCtx, PresenceStatement.class) != null;
     }
 
     /**
-     * Checks whether statement context is a mandatory node according to RFC6020
-     * or not.
+     * Checks whether statement context is a mandatory leaf, choice, anyxml,
+     * list or leaf-list according to RFC6020 or not.
      *
      * @param stmtCtx
      *            statement context
-     * @return true if it is a mandatory node according to RFC6020
+     * @return true if it is a mandatory leaf, choice, anyxml, list or leaf-list
+     *         according to RFC6020.
      */
-    public static boolean isMandatoryNode(final StatementContextBase<?, ?, ?> stmtCtx) {
-        return isMandatoryListOrLeafList(stmtCtx) || isMandatoryLeafChoiceOrAnyXML(stmtCtx);
-    }
-
-    private static boolean isMandatoryLeafChoiceOrAnyXML(final StatementContextBase<?, ?, ?> stmtCtx) {
+    public static boolean isMandatoryNode(final StmtContext<?, ?, ?> stmtCtx) {
         if (!(stmtCtx.getPublicDefinition() instanceof YangStmtMapping)) {
             return false;
         }
@@ -324,16 +334,6 @@ public final class StmtContextUtils {
         case CHOICE:
         case ANYXML:
             return Boolean.TRUE.equals(firstSubstatementAttributeOf(stmtCtx, MandatoryStatement.class));
-        default:
-            return false;
-        }
-    }
-
-    private static boolean isMandatoryListOrLeafList(final StatementContextBase<?, ?, ?> stmtCtx) {
-        if (!(stmtCtx.getPublicDefinition() instanceof YangStmtMapping)) {
-            return false;
-        }
-        switch ((YangStmtMapping) stmtCtx.getPublicDefinition()) {
         case LIST:
         case LEAF_LIST:
             final Integer minElements = firstSubstatementAttributeOf(stmtCtx, MinElementsStatement.class);
@@ -343,6 +343,24 @@ public final class StmtContextUtils {
         }
     }
 
+    /**
+     * Checks whether a statement context is a statement of supplied statement
+     * definition and whether it is not mandatory leaf, choice, anyxml, list or
+     * leaf-list according to RFC6020.
+     *
+     * @param stmtCtx
+     *            statement context
+     * @param stmtDef
+     *            statement definition
+     * @return true if supplied statement context is a statement of supplied
+     *         statement definition and if it is not mandatory leaf, choice,
+     *         anyxml, list or leaf-list according to RFC6020
+     */
+    public static boolean isNotMandatoryNodeOfType(final StmtContext<?, ?, ?> stmtCtx,
+            final StatementDefinition stmtDef) {
+        return stmtCtx.getPublicDefinition().equals(stmtDef) && !isMandatoryNode(stmtCtx);
+    }
+
     /**
      * Checks whether at least one ancestor of a StatementContext matches one
      * from collection of statement definitions.
@@ -383,8 +401,10 @@ public final class StmtContextUtils {
         Preconditions.checkNotNull(ctx);
         Preconditions.checkNotNull(ancestorType);
         Preconditions.checkNotNull(ancestorChildType);
+
         StmtContext<?, ?, ?> current = ctx.getParentContext();
-        while (!(current instanceof RootStatementContext)) {
+        StmtContext<?, ?, ?> parent = current.getParentContext();
+        while (parent != null) {
             if (ancestorType.equals(current.getPublicDefinition())) {
                 @SuppressWarnings("unchecked")
                 final Class<DT> ancestorChildTypeClass = (Class<DT>) ancestorChildType.getDeclaredRepresentationClass();
@@ -392,7 +412,9 @@ public final class StmtContextUtils {
                     return false;
                 }
             }
-            current = current.getParentContext();
+
+            current = parent;
+            parent = current.getParentContext();
         }
 
         return true;