Cleanup effectiveStatements() access
[yangtools.git] / yang / yang-parser-impl / src / main / java / org / opendaylight / yangtools / yang / parser / stmt / rfc6020 / effective / AbstractEffectiveDocumentedDataNodeContainer.java
index 78906ce7607dc7c673b8b9f940335df712677957..cd7371349d7ddd3171eea4014c1c5f821f79986a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
@@ -7,23 +7,29 @@
  */
 package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective;
 
-import java.util.Collection;
-import java.util.HashMap;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
 import java.util.HashSet;
-import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
-
-import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
-import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
 import java.util.Map;
 import java.util.Set;
 import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
+import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
+import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.GroupingDefinition;
 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
 import org.opendaylight.yangtools.yang.model.api.UsesNode;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
+import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
+import org.opendaylight.yangtools.yang.parser.spi.source.AugmentToChoiceNamespace;
+import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.YangValidationBundles;
 
-public abstract class AbstractEffectiveDocumentedDataNodeContainer<A, D extends DeclaredStatement<A>>
+abstract class AbstractEffectiveDocumentedDataNodeContainer<A, D extends DeclaredStatement<A>>
         extends AbstractEffectiveDocumentedNode<A, D> implements
         DataNodeContainer {
 
@@ -37,34 +43,66 @@ public abstract class AbstractEffectiveDocumentedDataNodeContainer<A, D extends
             final StmtContext<A, D, ?> ctx) {
         super(ctx);
 
-        Collection<? extends EffectiveStatement<?, ?>> effectiveSubstatements = effectiveSubstatements();
-
-        childNodes = new HashMap<QName, DataSchemaNode>();
-        groupings = new HashSet<GroupingDefinition>();
-        uses = new HashSet<UsesNode>();
-        typeDefinitions = new HashSet<TypeDefinition<?>>();
-        publicChildNodes = new HashSet<DataSchemaNode>();
-
-        for (EffectiveStatement<?, ?> effectiveStatement : effectiveSubstatements) {
-            if (effectiveStatement instanceof DataSchemaNode) {
-                DataSchemaNode dataSchemaNode = (DataSchemaNode) effectiveStatement;
-
-                childNodes.put(dataSchemaNode.getQName(), dataSchemaNode);
-                publicChildNodes.add(dataSchemaNode);
+        Map<QName, DataSchemaNode> mutableChildNodes = new LinkedHashMap<>();
+        Set<GroupingDefinition> mutableGroupings = new HashSet<>();
+        Set<UsesNode> mutableUses = new HashSet<>();
+        Set<TypeDefinition<?>> mutableTypeDefinitions = new LinkedHashSet<>();
+        Set<DataSchemaNode> mutablePublicChildNodes = new LinkedHashSet<>();
+
+        for (EffectiveStatement<?, ?> stmt : effectiveSubstatements()) {
+            if (stmt instanceof DataSchemaNode) {
+                final DataSchemaNode dataSchemaNode = (DataSchemaNode) stmt;
+                if (!mutableChildNodes.containsKey(dataSchemaNode.getQName())) {
+                    /**
+                     * Add case short hand when augmenting choice with short hand
+                     **/
+                    if (this instanceof AugmentationSchema
+                            && !(stmt instanceof ChoiceCaseNode || stmt instanceof ChoiceSchemaNode)
+                            && YangValidationBundles.SUPPORTED_CASE_SHORTHANDS.contains(stmt.statementDefinition())
+                            && Boolean.TRUE.equals(ctx.getFromNamespace(AugmentToChoiceNamespace.class, ctx))) {
+                        final CaseShorthandImpl caseShorthand = new CaseShorthandImpl(dataSchemaNode);
+                        mutableChildNodes.put(caseShorthand.getQName(), caseShorthand);
+                        mutablePublicChildNodes.add(caseShorthand);
+                    } else {
+                        mutableChildNodes.put(dataSchemaNode.getQName(), dataSchemaNode);
+                        mutablePublicChildNodes.add(dataSchemaNode);
+                    }
+                } else {
+                    throw EffectiveStmtUtils.createNameCollisionSourceException(ctx, stmt);
+                }
             }
-            if (effectiveStatement instanceof UsesNode) {
-                UsesNode usesNode = (UsesNode) effectiveStatement;
-                uses.add(usesNode);
+            if (stmt instanceof UsesNode) {
+                UsesNode usesNode = (UsesNode) stmt;
+                if (!mutableUses.contains(usesNode)) {
+                    mutableUses.add(usesNode);
+                } else {
+                    throw EffectiveStmtUtils.createNameCollisionSourceException(ctx, stmt);
+                }
             }
-            if (effectiveStatement instanceof TypeDefinition) {
-                TypeDefinition<?> typeDef = (TypeDefinition<?>) effectiveStatement;
-                typeDefinitions.add(typeDef);
+            if (stmt instanceof TypeDefEffectiveStatementImpl) {
+                TypeDefEffectiveStatementImpl typeDef = (TypeDefEffectiveStatementImpl) stmt;
+                TypeDefinition<?> type = typeDef.getTypeDefinition();
+                if (!mutableTypeDefinitions.contains(type)) {
+                    mutableTypeDefinitions.add(type);
+                } else {
+                    throw EffectiveStmtUtils.createNameCollisionSourceException(ctx, stmt);
+                }
             }
-            if (effectiveStatement instanceof GroupingDefinition) {
-                GroupingDefinition grp = (GroupingDefinition) effectiveStatement;
-                groupings.add(grp);
+            if (stmt instanceof GroupingDefinition) {
+                GroupingDefinition grp = (GroupingDefinition) stmt;
+                if (!mutableGroupings.contains(grp)) {
+                    mutableGroupings.add(grp);
+                } else {
+                    throw EffectiveStmtUtils.createNameCollisionSourceException(ctx, stmt);
+                }
             }
         }
+
+        this.childNodes = ImmutableMap.copyOf(mutableChildNodes);
+        this.groupings = ImmutableSet.copyOf(mutableGroupings);
+        this.publicChildNodes = ImmutableSet.copyOf(mutablePublicChildNodes);
+        this.typeDefinitions = ImmutableSet.copyOf(mutableTypeDefinitions);
+        this.uses = ImmutableSet.copyOf(mutableUses);
     }
 
     @Override
@@ -89,19 +127,8 @@ public abstract class AbstractEffectiveDocumentedDataNodeContainer<A, D extends
         return childNodes.get(name);
     }
 
-    @Override
-    public final DataSchemaNode getDataChildByName(final String name) {
-        for (DataSchemaNode node : childNodes.values()) {
-            if (node.getQName().getLocalName().equals(name)) {
-                return node;
-            }
-        }
-        return null;
-    }
-
     @Override
     public Set<UsesNode> getUses() {
         return uses;
     }
-
 }