ff139209b2f5964228d9391c52972e2c06579468
[yangtools.git] / yang / yang-parser-impl / src / main / java / org / opendaylight / yangtools / yang / parser / stmt / reactor / RootStatementContext.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.reactor;
9
10 import com.google.common.base.Optional;
11 import com.google.common.base.Preconditions;
12 import com.google.common.base.Verify;
13 import com.google.common.collect.ImmutableList;
14 import java.util.ArrayList;
15 import java.util.Collection;
16 import java.util.Map;
17 import javax.annotation.Nonnull;
18 import javax.annotation.Nullable;
19 import org.opendaylight.yangtools.yang.common.QNameModule;
20 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
21 import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
22 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
23 import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace;
24 import org.opendaylight.yangtools.yang.parser.spi.meta.CopyType;
25 import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.NamespaceStorageNode;
26 import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.Registry;
27 import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.StorageNodeType;
28 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
29 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils;
30 import org.opendaylight.yangtools.yang.parser.spi.source.IncludedModuleContext;
31
32 /**
33  * Root statement class for a YANG source. All statements defined in that YANG source are mapped underneath an instance
34  * of this class, hence recursive lookups from them cross this class.
35  */
36 public class RootStatementContext<A, D extends DeclaredStatement<A>, E extends EffectiveStatement<A, D>> extends
37         StatementContextBase<A, D, E> {
38
39     private final SourceSpecificContext sourceContext;
40     private final A argument;
41
42     /**
43      * References to RootStatementContext of submodules which are included in this source.
44      */
45     private Collection<RootStatementContext<?, ?, ?>> includedContexts = ImmutableList.of();
46
47     RootStatementContext(final ContextBuilder<A, D, E> builder, final SourceSpecificContext sourceContext) {
48         super(builder);
49         this.sourceContext = Preconditions.checkNotNull(sourceContext);
50         this.argument = builder.getDefinition().parseArgumentValue(this, builder.getRawArgument());
51     }
52
53     RootStatementContext(final RootStatementContext<A, D, E> original, final QNameModule newQNameModule,
54         final CopyType typeOfCopy) {
55         super(original);
56
57         sourceContext = Preconditions.checkNotNull(original.sourceContext);
58         this.argument = original.argument;
59
60         final Collection<StatementContextBase<?, ?, ?>> declared = original.declaredSubstatements();
61         final Collection<StatementContextBase<?, ?, ?>> effective = original.effectiveSubstatements();
62         final Collection<StatementContextBase<?, ?, ?>> buffer = new ArrayList<>(declared.size() + effective.size());
63
64         for (final StatementContextBase<?, ?, ?> stmtContext : declared) {
65             if (StmtContextUtils.areFeaturesSupported(stmtContext)) {
66                 buffer.add(stmtContext.createCopy(newQNameModule, this, typeOfCopy));
67             }
68         }
69         for (final StmtContext<?, ?, ?> stmtContext : effective) {
70             buffer.add(stmtContext.createCopy(newQNameModule, this, typeOfCopy));
71         }
72
73         addEffectiveSubstatements(buffer);
74     }
75
76     /**
77      * @return null as root cannot have parent
78      */
79     @Override
80     public StatementContextBase<?, ?, ?> getParentContext() {
81         return null;
82     }
83
84     /**
85      * @return namespace storage of source context
86      */
87     @Override
88     public NamespaceStorageNode getParentNamespaceStorage() {
89         return sourceContext;
90     }
91
92     /**
93      * @return registry of source context
94      */
95     @Override
96     public Registry getBehaviourRegistry() {
97         return sourceContext;
98     }
99
100     @Override
101     public StorageNodeType getStorageNodeType() {
102         return StorageNodeType.ROOT_STATEMENT_LOCAL;
103     }
104     /**
105      * @return this as its own root
106      */
107     @Nonnull
108     @Override
109     public RootStatementContext<?, ?, ?> getRoot() {
110         return this;
111     }
112
113     SourceSpecificContext getSourceContext() {
114         return sourceContext;
115     }
116
117     @Override
118     public A getStatementArgument() {
119         return argument;
120     }
121
122     /**
123      * @return copy of this considering {@link CopyType} (augment, uses)
124      *
125      * @throws org.opendaylight.yangtools.yang.parser.spi.source.SourceException instance of SourceException
126      */
127     @Override
128     public StatementContextBase<?, ?, ?> createCopy(final StatementContextBase<?, ?, ?> newParent,
129             final CopyType typeOfCopy) {
130         return createCopy(null, newParent, typeOfCopy);
131     }
132
133     /**
134      * @return copy of this considering {@link CopyType} (augment, uses)
135      *
136      * @throws org.opendaylight.yangtools.yang.parser.spi.source.SourceException instance of SourceException
137      */
138     @Override
139     public StatementContextBase<A, D, E> createCopy(final QNameModule newQNameModule,
140             final StatementContextBase<?, ?, ?> newParent, final CopyType typeOfCopy) {
141         final RootStatementContext<A, D, E> copy = new RootStatementContext<>(this, newQNameModule, typeOfCopy);
142
143         copy.appendCopyHistory(typeOfCopy, this.getCopyHistory());
144
145         if (this.getOriginalCtx() != null) {
146             copy.setOriginalCtx(this.getOriginalCtx());
147         } else {
148             copy.setOriginalCtx(this);
149         }
150         definition().onStatementAdded(copy);
151         return copy;
152     }
153
154     @Nonnull
155     @Override
156     public Optional<SchemaPath> getSchemaPath() {
157         return Optional.of(SchemaPath.ROOT);
158     }
159
160     /**
161      * @return true
162      */
163     @Override
164     public boolean isRootContext() {
165         return true;
166     }
167
168     @Override
169     public boolean isConfiguration() {
170         return true;
171     }
172
173     @Override
174     public boolean isEnabledSemanticVersioning() {
175         return sourceContext.isEnabledSemanticVersioning();
176     }
177
178     @Override
179     public <K, V, N extends IdentifierNamespace<K, V>> void addToLocalStorage(final Class<N> type, final K key,
180             final V value) {
181         if (IncludedModuleContext.class.isAssignableFrom(type)) {
182             if (includedContexts.isEmpty()) {
183                 includedContexts = new ArrayList<>(1);
184             }
185             Verify.verify(value instanceof RootStatementContext);
186             includedContexts.add((RootStatementContext<?, ?, ?>) value);
187         }
188         super.addToLocalStorage(type, key, value);
189     }
190
191     @Override
192     public <K, V, N extends IdentifierNamespace<K, V>> V getFromLocalStorage(final Class<N> type, final K key) {
193         final V potentialLocal = super.getFromLocalStorage(type, key);
194         if (potentialLocal != null) {
195             return potentialLocal;
196         }
197         for (final NamespaceStorageNode includedSource : includedContexts) {
198             final V potential = includedSource.getFromLocalStorage(type, key);
199             if (potential != null) {
200                 return potential;
201             }
202         }
203         return null;
204     }
205
206     @Nullable
207     @Override
208     public <K, V, N extends IdentifierNamespace<K, V>> Map<K, V> getAllFromLocalStorage(final Class<N> type) {
209         final Map<K, V> potentialLocal = super.getAllFromLocalStorage(type);
210         if (potentialLocal != null) {
211             return potentialLocal;
212         }
213         for (final NamespaceStorageNode includedSource : includedContexts) {
214             final Map<K, V> potential = includedSource.getAllFromLocalStorage(type);
215             if (potential != null) {
216                 return potential;
217             }
218         }
219         return null;
220     }
221 }