Fix yang-data extension definition
[yangtools.git] / parser / rfc8040-parser-support / src / main / java / org / opendaylight / yangtools / rfc8040 / parser / YangDataEffectiveStatementImpl.java
index 1898e738d1f72fe5bda58572a2aef95b023f84e3..13440a836790e82955fadd63b711aea78c3976ef 100644 (file)
@@ -7,80 +7,73 @@
  */
 package org.opendaylight.yangtools.rfc8040.parser;
 
+import static com.google.common.base.Verify.verify;
 import static java.util.Objects.requireNonNull;
 
 import com.google.common.annotations.Beta;
-import com.google.common.base.MoreObjects;
-import com.google.common.base.Verify;
 import com.google.common.collect.ImmutableList;
+import java.util.Map;
+import java.util.Optional;
 import org.eclipse.jdt.annotation.NonNull;
-import org.eclipse.jdt.annotation.Nullable;
 import org.opendaylight.yangtools.rfc8040.model.api.YangDataEffectiveStatement;
 import org.opendaylight.yangtools.rfc8040.model.api.YangDataSchemaNode;
 import org.opendaylight.yangtools.rfc8040.model.api.YangDataStatement;
 import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.SchemaNodeDefaults;
-import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
-import org.opendaylight.yangtools.yang.model.api.stmt.ContainerEffectiveStatement;
-import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.UnknownEffectiveStatementBase;
+import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace;
+import org.opendaylight.yangtools.yang.model.api.stmt.DataTreeAwareEffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.DataTreeEffectiveStatement;
+import org.opendaylight.yangtools.yang.model.spi.meta.AbstractEffectiveUnknownSchmemaNode;
+import org.opendaylight.yangtools.yang.model.spi.meta.EffectiveStatementMixins.DataNodeContainerMixin;
 import org.opendaylight.yangtools.yang.parser.spi.meta.EffectiveStmtCtx.Current;
-import org.opendaylight.yangtools.yang.parser.spi.meta.SchemaPathSupport;
 
 @Beta
-final class YangDataEffectiveStatementImpl extends UnknownEffectiveStatementBase<String, YangDataStatement>
-        implements YangDataEffectiveStatement, YangDataSchemaNode {
-
-    private final @Nullable SchemaPath path;
-    private final @NonNull QName argumentQName;
-    private final @NonNull ContainerEffectiveStatement container;
+final class YangDataEffectiveStatementImpl extends AbstractEffectiveUnknownSchmemaNode<String, YangDataStatement>
+        implements YangDataEffectiveStatement, YangDataSchemaNode, DataNodeContainerMixin<String, YangDataStatement> {
+    private final @NonNull DataSchemaNode child;
 
     YangDataEffectiveStatementImpl(final Current<String, YangDataStatement> stmt,
-             final ImmutableList<? extends EffectiveStatement<?, ?>> substatements, final QName qname) {
-        super(stmt, substatements);
-        this.argumentQName = requireNonNull(qname);
-
-        path = SchemaPathSupport.toOptionalPath(stmt.getEffectiveParent().getSchemaPath().createChild(qname));
-        container = findFirstEffectiveSubstatement(ContainerEffectiveStatement.class).get();
-
-        // TODO: this is strong binding of two API contracts. Unfortunately ContainerEffectiveStatement design is
-        //       incomplete.
-        Verify.verify(container instanceof ContainerSchemaNode);
+             final ImmutableList<? extends EffectiveStatement<?, ?>> substatements, final DataSchemaNode child) {
+        super(stmt.declared(), stmt.argument(), stmt.history(), substatements);
+        this.child = requireNonNull(child);
     }
 
     @Override
     public QName getQName() {
-        return argumentQName;
+        return child.getQName();
     }
 
     @Override
-    @Deprecated
-    public SchemaPath getPath() {
-        return SchemaNodeDefaults.throwUnsupportedIfNull(this, path);
+    public DataSchemaNode dataChildByName(final QName name) {
+        return name.equals(child.getQName()) ? child : null;
     }
 
     @Override
-    public ContainerEffectiveStatement getContainer() {
-        return container;
+    public YangDataEffectiveStatement asEffectiveStatement() {
+        return this;
     }
 
     @Override
-    public ContainerSchemaNode getContainerSchemaNode() {
-        // Verified in the constructor
-        return (ContainerSchemaNode) container;
-    }
+    protected <K, V, N extends IdentifierNamespace<K, V>> Optional<? extends Map<K, V>> getNamespaceContents(
+            final Class<N> namespace) {
+        if (SchemaTreeNamespace.class.equals(namespace)) {
+            return castChild();
+        }
+        if (DataTreeNamespace.class.equals(namespace)) {
+            if (child instanceof DataTreeEffectiveStatement) {
+                return castChild();
+            }
 
-    @Override
-    public YangDataEffectiveStatement asEffectiveStatement() {
-        return this;
+            // A schema tree statement which *has to* know about data tree -- just forward it
+            verify(child instanceof DataTreeAwareEffectiveStatement, "Unexpected child %s", child);
+            return Optional.of(((DataTreeAwareEffectiveStatement<?, ?>) child).getAll(namespace));
+        }
+        return super.getNamespaceContents(namespace);
     }
 
-    @Override
-    public String toString() {
-        return MoreObjects.toStringHelper(this).omitNullValues()
-                .add("qname", argumentQName)
-                .add("path", path)
-                .add("container", container).toString();
+    @SuppressWarnings("unchecked")
+    private <K, V> Optional<Map<K, V>> castChild() {
+        return Optional.of((Map<K, V>) Map.of(child.getQName(), child));
     }
 }