Cleanup effectiveStatements() access
[yangtools.git] / yang / yang-parser-impl / src / main / java / org / opendaylight / yangtools / yang / parser / stmt / rfc6020 / effective / AbstractEffectiveDocumentedDataNodeContainer.java
1 /*
2  * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective;
9
10 import com.google.common.collect.ImmutableMap;
11 import com.google.common.collect.ImmutableSet;
12 import java.util.HashSet;
13 import java.util.LinkedHashMap;
14 import java.util.LinkedHashSet;
15 import java.util.Map;
16 import java.util.Set;
17 import org.opendaylight.yangtools.yang.common.QName;
18 import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
19 import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
20 import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode;
21 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
22 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
23 import org.opendaylight.yangtools.yang.model.api.GroupingDefinition;
24 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
25 import org.opendaylight.yangtools.yang.model.api.UsesNode;
26 import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
27 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
28 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
29 import org.opendaylight.yangtools.yang.parser.spi.source.AugmentToChoiceNamespace;
30 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.YangValidationBundles;
31
32 abstract class AbstractEffectiveDocumentedDataNodeContainer<A, D extends DeclaredStatement<A>>
33         extends AbstractEffectiveDocumentedNode<A, D> implements
34         DataNodeContainer {
35
36     private final Map<QName, DataSchemaNode> childNodes;
37     private final Set<GroupingDefinition> groupings;
38     private final Set<UsesNode> uses;
39     private final Set<TypeDefinition<?>> typeDefinitions;
40     private final Set<DataSchemaNode> publicChildNodes;
41
42     protected AbstractEffectiveDocumentedDataNodeContainer(
43             final StmtContext<A, D, ?> ctx) {
44         super(ctx);
45
46         Map<QName, DataSchemaNode> mutableChildNodes = new LinkedHashMap<>();
47         Set<GroupingDefinition> mutableGroupings = new HashSet<>();
48         Set<UsesNode> mutableUses = new HashSet<>();
49         Set<TypeDefinition<?>> mutableTypeDefinitions = new LinkedHashSet<>();
50         Set<DataSchemaNode> mutablePublicChildNodes = new LinkedHashSet<>();
51
52         for (EffectiveStatement<?, ?> stmt : effectiveSubstatements()) {
53             if (stmt instanceof DataSchemaNode) {
54                 final DataSchemaNode dataSchemaNode = (DataSchemaNode) stmt;
55                 if (!mutableChildNodes.containsKey(dataSchemaNode.getQName())) {
56                     /**
57                      * Add case short hand when augmenting choice with short hand
58                      **/
59                     if (this instanceof AugmentationSchema
60                             && !(stmt instanceof ChoiceCaseNode || stmt instanceof ChoiceSchemaNode)
61                             && YangValidationBundles.SUPPORTED_CASE_SHORTHANDS.contains(stmt.statementDefinition())
62                             && Boolean.TRUE.equals(ctx.getFromNamespace(AugmentToChoiceNamespace.class, ctx))) {
63                         final CaseShorthandImpl caseShorthand = new CaseShorthandImpl(dataSchemaNode);
64                         mutableChildNodes.put(caseShorthand.getQName(), caseShorthand);
65                         mutablePublicChildNodes.add(caseShorthand);
66                     } else {
67                         mutableChildNodes.put(dataSchemaNode.getQName(), dataSchemaNode);
68                         mutablePublicChildNodes.add(dataSchemaNode);
69                     }
70                 } else {
71                     throw EffectiveStmtUtils.createNameCollisionSourceException(ctx, stmt);
72                 }
73             }
74             if (stmt instanceof UsesNode) {
75                 UsesNode usesNode = (UsesNode) stmt;
76                 if (!mutableUses.contains(usesNode)) {
77                     mutableUses.add(usesNode);
78                 } else {
79                     throw EffectiveStmtUtils.createNameCollisionSourceException(ctx, stmt);
80                 }
81             }
82             if (stmt instanceof TypeDefEffectiveStatementImpl) {
83                 TypeDefEffectiveStatementImpl typeDef = (TypeDefEffectiveStatementImpl) stmt;
84                 TypeDefinition<?> type = typeDef.getTypeDefinition();
85                 if (!mutableTypeDefinitions.contains(type)) {
86                     mutableTypeDefinitions.add(type);
87                 } else {
88                     throw EffectiveStmtUtils.createNameCollisionSourceException(ctx, stmt);
89                 }
90             }
91             if (stmt instanceof GroupingDefinition) {
92                 GroupingDefinition grp = (GroupingDefinition) stmt;
93                 if (!mutableGroupings.contains(grp)) {
94                     mutableGroupings.add(grp);
95                 } else {
96                     throw EffectiveStmtUtils.createNameCollisionSourceException(ctx, stmt);
97                 }
98             }
99         }
100
101         this.childNodes = ImmutableMap.copyOf(mutableChildNodes);
102         this.groupings = ImmutableSet.copyOf(mutableGroupings);
103         this.publicChildNodes = ImmutableSet.copyOf(mutablePublicChildNodes);
104         this.typeDefinitions = ImmutableSet.copyOf(mutableTypeDefinitions);
105         this.uses = ImmutableSet.copyOf(mutableUses);
106     }
107
108     @Override
109     public final Set<TypeDefinition<?>> getTypeDefinitions() {
110         return typeDefinitions;
111     }
112
113     @Override
114     public final Set<DataSchemaNode> getChildNodes() {
115         return publicChildNodes;
116     }
117
118     @Override
119     public final Set<GroupingDefinition> getGroupings() {
120         return groupings;
121     }
122
123     @Override
124     public final DataSchemaNode getDataChildByName(final QName name) {
125         // Child nodes are keyed by their container name, so we can do a direct
126         // lookup
127         return childNodes.get(name);
128     }
129
130     @Override
131     public Set<UsesNode> getUses() {
132         return uses;
133     }
134 }