Refactor ListEffectiveStatementImpl
[yangtools.git] / yang / yang-parser-rfc7950 / src / main / java / org / opendaylight / yangtools / yang / parser / rfc7950 / stmt / EffectiveStatementMixins.java
index 46f09b90f86149663056bd383de6ec7dae632bcc..1584c90d12d7ac45f6cf5506d06e05857c0ed71b 100644 (file)
@@ -10,28 +10,41 @@ package org.opendaylight.yangtools.yang.parser.rfc7950.stmt;
 import com.google.common.annotations.Beta;
 import com.google.common.collect.Collections2;
 import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
 import java.util.Collection;
 import java.util.List;
 import java.util.Optional;
+import java.util.Set;
 import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.opendaylight.yangtools.concepts.Mutable;
 import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.ActionDefinition;
+import org.opendaylight.yangtools.yang.model.api.ActionNodeContainer;
 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.CopyableNode;
+import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.DocumentedNode;
+import org.opendaylight.yangtools.yang.model.api.GroupingDefinition;
 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.RevisionAwareXPath;
 import org.opendaylight.yangtools.yang.model.api.SchemaNode;
 import org.opendaylight.yangtools.yang.model.api.Status;
+import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
 import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.UsesNode;
 import org.opendaylight.yangtools.yang.model.api.WhenConditionAware;
 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.stmt.DescriptionEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.ReferenceEffectiveStatement;
+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;
@@ -50,9 +63,28 @@ public final class EffectiveStatementMixins {
             return (Collection<T>) Collections2.filter(effectiveSubstatements(), type::isInstance);
         }
 
+        // FIXME: YANGTOOLS-1068: eliminate this once we can return collections
         default <T> List<T> filterEffectiveStatementsList(final Class<T> type) {
-            return effectiveSubstatements().stream().filter(type::isInstance).map(type::cast)
-                    .collect(ImmutableList.toImmutableList());
+            return ImmutableList.copyOf(filterEffectiveStatements(type));
+        }
+
+        // FIXME: YANGTOOLS-1068: eliminate this once we can return collections
+        default <T> Set<T> filterEffectiveStatementsSet(final Class<T> type) {
+            return ImmutableSet.copyOf(filterEffectiveStatements(type));
+        }
+    }
+
+    /**
+     * Bridge between {@link EffectiveStatement} and {@link AugmentationTarget}.
+     *
+     * @param <A> Argument type ({@link Void} if statement does not have argument.)
+     * @param <D> Class representing declared version of this statement.
+     */
+    public interface AugmentationTargetMixin<A, D extends DeclaredStatement<A>>
+            extends Mixin<A, D>, AugmentationTarget {
+        @Override
+        default Set<AugmentationSchemaNode> getAvailableAugmentations() {
+            return filterEffectiveStatementsSet(AugmentationSchemaNode.class);
         }
     }
 
@@ -70,6 +102,34 @@ public final class EffectiveStatementMixins {
         }
     }
 
+    /**
+     * Bridge between {@link EffectiveStatementWithFlags} and {@link ActionNodeContainer}.
+     *
+     * @param <A> Argument type ({@link Void} if statement does not have argument.)
+     * @param <D> Class representing declared version of this statement.
+     */
+    public interface ActionNodeContainerMixin<A, D extends DeclaredStatement<A>>
+            extends Mixin<A, D>, ActionNodeContainer {
+        @Override
+        default Set<ActionDefinition> getActions() {
+            return filterEffectiveStatementsSet(ActionDefinition.class);
+        }
+    }
+
+    /**
+     * Bridge between {@link EffectiveStatementWithFlags} and {@link NotificationNodeContainer}.
+     *
+     * @param <A> Argument type ({@link Void} if statement does not have argument.)
+     * @param <D> Class representing declared version of this statement.
+     */
+    public interface NotificationNodeContainerMixin<A, D extends DeclaredStatement<A>>
+            extends Mixin<A, D>, NotificationNodeContainer {
+        @Override
+        default Set<NotificationDefinition> getNotifications() {
+            return filterEffectiveStatementsSet(NotificationDefinition.class);
+        }
+    }
+
     /**
      * Bridge between {@link EffectiveStatementWithFlags} and {@link MustConstraintAware}.
      *
@@ -96,6 +156,37 @@ public final class EffectiveStatementMixins {
         }
     }
 
+    /**
+     * Bridge between {@link EffectiveStatementWithFlags} and {@link DataNodeContainer}.
+     *
+     * @param <A> Argument type ({@link Void} if statement does not have argument.)
+     * @param <D> Class representing declared version of this statement.
+     */
+    public interface DataNodeContainerMixin<A, D extends DeclaredStatement<A>> extends DataNodeContainer, Mixin<A, D> {
+        @Override
+        default Set<TypeDefinition<?>> getTypeDefinitions() {
+            // TODO: the cast here is needed to work around Java 11 javac type inference issue
+            return (Set) effectiveSubstatements().stream().filter(TypedefEffectiveStatement.class::isInstance)
+                    .map(stmt -> ((TypedefEffectiveStatement) stmt).getTypeDefinition())
+                    .collect(ImmutableSet.toImmutableSet());
+        }
+
+        @Override
+        default Collection<DataSchemaNode> getChildNodes() {
+            return filterEffectiveStatements(DataSchemaNode.class);
+        }
+
+        @Override
+        default Set<GroupingDefinition> getGroupings() {
+            return filterEffectiveStatementsSet(GroupingDefinition.class);
+        }
+
+        @Override
+        default Set<UsesNode> getUses() {
+            return filterEffectiveStatementsSet(UsesNode.class);
+        }
+    }
+
     /**
      * Bridge between {@link EffectiveStatementWithFlags} and {@link DataSchemaNode}.
      *