Make CopyHistory implement CopyableNode
[yangtools.git] / yang / yang-parser-rfc7950 / src / main / java / org / opendaylight / yangtools / yang / parser / rfc7950 / stmt / EffectiveStatementMixins.java
index fef94246002d95821d20a3164d0bb1551b72cde5..5e0331da7da8b0880b6688892d1e2324a8f0a558 100644 (file)
@@ -7,10 +7,9 @@
  */
 package org.opendaylight.yangtools.yang.parser.rfc7950.stmt;
 
-import static com.google.common.base.Verify.verify;
-
 import com.google.common.annotations.Beta;
 import com.google.common.base.MoreObjects;
+import com.google.common.base.Strings;
 import com.google.common.collect.Collections2;
 import com.google.common.collect.ImmutableSet;
 import java.util.Collection;
@@ -25,20 +24,21 @@ import org.opendaylight.yangtools.yang.model.api.AddedByUsesAware;
 import org.opendaylight.yangtools.yang.model.api.AugmentationSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.AugmentationTarget;
 import org.opendaylight.yangtools.yang.model.api.ConstraintMetaDefinition;
-import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.ContainerLike;
 import org.opendaylight.yangtools.yang.model.api.CopyableNode;
 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.DerivableSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.DocumentedNode;
 import org.opendaylight.yangtools.yang.model.api.GroupingDefinition;
+import org.opendaylight.yangtools.yang.model.api.InputSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.MandatoryAware;
 import org.opendaylight.yangtools.yang.model.api.MustConstraintAware;
 import org.opendaylight.yangtools.yang.model.api.MustDefinition;
 import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;
 import org.opendaylight.yangtools.yang.model.api.NotificationNodeContainer;
 import org.opendaylight.yangtools.yang.model.api.OperationDefinition;
-import org.opendaylight.yangtools.yang.model.api.RevisionAwareXPath;
+import org.opendaylight.yangtools.yang.model.api.OutputSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.SchemaNode;
 import org.opendaylight.yangtools.yang.model.api.Status;
 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
@@ -56,7 +56,7 @@ import org.opendaylight.yangtools.yang.model.api.stmt.ReferenceEffectiveStatemen
 import org.opendaylight.yangtools.yang.model.api.stmt.TypedefEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.WhenEffectiveStatement;
 import org.opendaylight.yangtools.yang.parser.spi.meta.CopyHistory;
-import org.opendaylight.yangtools.yang.parser.spi.meta.CopyType;
+import org.opendaylight.yangtools.yang.xpath.api.YangXPathExpression.QualifiedBound;
 
 /**
  * Mix-in interfaces providing services required by SchemaNode et al. These interfaces provide implementations, or
@@ -67,7 +67,7 @@ public final class EffectiveStatementMixins {
     // Marker interface requiring all mixins to be derived from EffectiveStatement.
     private interface Mixin<A, D extends DeclaredStatement<A>> extends EffectiveStatement<A, D> {
         @SuppressWarnings("unchecked")
-        default <T> Collection<? extends T> filterEffectiveStatements(final Class<T> type) {
+        default <T> @NonNull Collection<? extends T> filterEffectiveStatements(final Class<T> type) {
             // Yeah, this is not nice, but saves one transformation
             return (Collection<? extends T>) Collections2.filter(effectiveSubstatements(), type::isInstance);
         }
@@ -304,6 +304,21 @@ public final class EffectiveStatementMixins {
         }
     }
 
+    /**
+     * Bridge between {@link EffectiveStatementWithFlags} and {@link UnknownSchemaNode}.
+     *
+     * @param <A> Argument type ({@link Void} if statement does not have argument.)
+     * @param <D> Class representing declared version of this statement.
+     */
+    public interface UnknownSchemaNodeMixin<A, D extends DeclaredStatement<A>>
+            extends SchemaNodeMixin<A, D>, CopyableMixin<A, D>, UnknownSchemaNode {
+
+        @Override
+        default String getNodeParameter() {
+            return Strings.nullToEmpty(getDeclared().rawArgument());
+        }
+    }
+
     /**
      * Bridge between {@link EffectiveStatementWithFlags} and {@code ordered-by} statement.
      *
@@ -325,7 +340,7 @@ public final class EffectiveStatementMixins {
      */
     public interface WhenConditionMixin<A, D extends DeclaredStatement<A>> extends Mixin<A, D>, WhenConditionAware {
         @Override
-        default Optional<RevisionAwareXPath> getWhenCondition() {
+        default Optional<QualifiedBound> getWhenCondition() {
             return findFirstEffectiveSubstatementArgument(WhenEffectiveStatement.class);
         }
     }
@@ -336,7 +351,7 @@ public final class EffectiveStatementMixins {
      * @param <D> Class representing declared version of this statement.
      */
     public interface OperationContainerMixin<D extends DeclaredStatement<QName>>
-            extends ContainerSchemaNode, DocumentedNodeMixin.WithStatus<QName, D>, DataNodeContainerMixin<QName, D>,
+            extends ContainerLike, DocumentedNodeMixin.WithStatus<QName, D>, DataNodeContainerMixin<QName, D>,
                     MustConstraintMixin<QName, D>, WhenConditionMixin<QName, D>, AugmentationTargetMixin<QName, D>,
                     SchemaNodeMixin<QName, D>, CopyableMixin<QName, D> {
         @Override
@@ -369,12 +384,6 @@ public final class EffectiveStatementMixins {
             return false;
         }
 
-        @Override
-        default boolean isPresenceContainer() {
-            // FIXME: this should not really be here
-            return false;
-        }
-
         default String defaultToString() {
             return MoreObjects.toStringHelper(this).add("path", getPath()).toString();
         }
@@ -417,13 +426,13 @@ public final class EffectiveStatementMixins {
         }
 
         @Override
-        default ContainerSchemaNode getInput() {
-            return findAsContainer(this, InputEffectiveStatement.class);
+        default InputSchemaNode getInput() {
+            return findAsContainer(this, InputEffectiveStatement.class, InputSchemaNode.class);
         }
 
         @Override
-        default ContainerSchemaNode getOutput() {
-            return findAsContainer(this, OutputEffectiveStatement.class);
+        default OutputSchemaNode getOutput() {
+            return findAsContainer(this, OutputEffectiveStatement.class, OutputSchemaNode.class);
         }
     }
 
@@ -472,20 +481,8 @@ public final class EffectiveStatementMixins {
             }
 
             public FlagsBuilder setHistory(final CopyHistory history) {
-                int bits;
-                if (history.contains(CopyType.ADDED_BY_USES_AUGMENTATION)) {
-                    bits = AUGMENTING | ADDED_BY_USES;
-                } else {
-                    bits = 0;
-                    if (history.contains(CopyType.ADDED_BY_AUGMENTATION)) {
-                        bits |= AUGMENTING;
-                    }
-                    if (history.contains(CopyType.ADDED_BY_USES)) {
-                        bits |= ADDED_BY_USES;
-                    }
-                }
-
-                flags = flags & ~MASK_HISTORY | bits;
+                flags = flags & ~MASK_HISTORY
+                    | (history.isAugmenting() ? AUGMENTING : 0) | (history.isAddedByUses() ? ADDED_BY_USES : 0);
                 return this;
             }
 
@@ -545,12 +542,9 @@ public final class EffectiveStatementMixins {
     private EffectiveStatementMixins() {
     }
 
-    static ContainerSchemaNode findAsContainer(final EffectiveStatement<?, ?> stmt,
-            final Class<? extends EffectiveStatement<QName, ?>> type) {
-        final EffectiveStatement<?, ?> statement = stmt.findFirstEffectiveSubstatement(type).get();
-        verify(statement instanceof ContainerSchemaNode, "Child statement %s is not a ContainerSchemaNode",
-            statement);
-        return (ContainerSchemaNode) statement;
+    static <T extends ContainerLike> T findAsContainer(final EffectiveStatement<?, ?> stmt,
+            final Class<? extends EffectiveStatement<QName, ?>> type, Class<T> target) {
+        return target.cast(stmt.findFirstEffectiveSubstatement(type).get());
     }
 
     static Collection<? extends TypeDefinition<?>> filterTypeDefinitions(final Mixin<?, ?> stmt) {