Convert parser-{reactor,spi} classes to JDT annotations
[yangtools.git] / yang / yang-parser-reactor / src / main / java / org / opendaylight / yangtools / yang / parser / stmt / reactor / CrossSourceStatementReactor.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 static com.google.common.base.Preconditions.checkState;
11 import static java.util.Objects.requireNonNull;
12
13 import com.google.common.collect.ImmutableMap;
14 import com.google.common.collect.SetMultimap;
15 import java.util.Arrays;
16 import java.util.Collection;
17 import java.util.EnumMap;
18 import java.util.Map;
19 import java.util.Set;
20 import org.eclipse.jdt.annotation.NonNull;
21 import org.opendaylight.yangtools.yang.common.QName;
22 import org.opendaylight.yangtools.yang.common.QNameModule;
23 import org.opendaylight.yangtools.yang.model.repo.api.StatementParserMode;
24 import org.opendaylight.yangtools.yang.parser.spi.meta.ModelProcessingPhase;
25 import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
26 import org.opendaylight.yangtools.yang.parser.spi.meta.StatementSupportBundle;
27 import org.opendaylight.yangtools.yang.parser.spi.source.StatementStreamSource;
28 import org.opendaylight.yangtools.yang.parser.spi.validation.ValidationBundlesNamespace.ValidationBundleType;
29
30 public final class CrossSourceStatementReactor {
31     private final Map<ModelProcessingPhase, StatementSupportBundle> supportedTerminology;
32     private final Map<ValidationBundleType, Collection<?>> supportedValidation;
33
34     CrossSourceStatementReactor(final Map<ModelProcessingPhase, StatementSupportBundle> supportedTerminology,
35             final Map<ValidationBundleType, Collection<?>> supportedValidation) {
36         this.supportedTerminology = ImmutableMap.copyOf(supportedTerminology);
37         this.supportedValidation = ImmutableMap.copyOf(supportedValidation);
38     }
39
40     /**
41      * Create a new {@link Builder}.
42      *
43      * @return A new builder.
44      */
45     public static @NonNull Builder builder() {
46         return new Builder();
47     }
48
49     /**
50      * Start a new reactor build using the default statement parser mode with all features and deviations enabled.
51      *
52      * @return A new {@link BuildAction}.
53      */
54     public @NonNull BuildAction newBuild() {
55         return newBuild(StatementParserMode.DEFAULT_MODE);
56     }
57
58     /**
59      * Start a new reactor build using the specified statement parser mode and enabling all features and deviations.
60      *
61      * @param statementParserMode Parser mode to use
62      * @return A new {@link BuildAction}.
63      * @throws NullPointerException if statementParserMode is null
64      */
65     public @NonNull BuildAction newBuild(final StatementParserMode statementParserMode) {
66         return new BuildAction(statementParserMode);
67     }
68
69     public static class Builder implements org.opendaylight.yangtools.concepts.Builder<CrossSourceStatementReactor> {
70         private final Map<ValidationBundleType, Collection<?>> validationBundles =
71                 new EnumMap<>(ValidationBundleType.class);
72         private final Map<ModelProcessingPhase, StatementSupportBundle> bundles =
73                 new EnumMap<>(ModelProcessingPhase.class);
74
75         public @NonNull Builder setBundle(final ModelProcessingPhase phase, final StatementSupportBundle bundle) {
76             bundles.put(phase, bundle);
77             return this;
78         }
79
80         public @NonNull Builder setValidationBundle(final ValidationBundleType type,
81                 final Collection<?> validationBundle) {
82             validationBundles.put(type, validationBundle);
83             return this;
84         }
85
86         @Override
87         public CrossSourceStatementReactor build() {
88             return new CrossSourceStatementReactor(bundles, validationBundles);
89         }
90     }
91
92     public class BuildAction {
93         private final BuildGlobalContext context;
94         private boolean supportedFeaturesSet = false;
95         private boolean modulesDeviatedByModulesSet = false;
96
97         BuildAction(final @NonNull StatementParserMode statementParserMode) {
98             this.context = new BuildGlobalContext(supportedTerminology, supportedValidation,
99                 requireNonNull(statementParserMode));
100         }
101
102         /**
103          * Add main source. All main sources are present in resulting SchemaContext.
104          *
105          * @param source
106          *            which should be added into main sources
107          * @return This build action, for fluent use.
108          */
109         public @NonNull BuildAction addSource(final StatementStreamSource source) {
110             context.addSource(source);
111             return this;
112         }
113
114         /**
115          * Add main sources. All main sources are present in resulting SchemaContext.
116          *
117          * @param sources
118          *            which should be added into main sources
119          * @return This build action, for fluent use.
120          */
121         public @NonNull BuildAction addSources(final StatementStreamSource... sources) {
122             addSources(Arrays.asList(sources));
123             return this;
124         }
125
126         public @NonNull BuildAction addSources(final @NonNull Collection<? extends StatementStreamSource> sources) {
127             for (final StatementStreamSource source : sources) {
128                 context.addSource(requireNonNull(source));
129             }
130             return this;
131         }
132
133         /**
134          * Add library sources. Only library sources required by main sources are present in resulting SchemaContext.
135          * Any other library sources are ignored and this also applies to error reporting.
136          *
137          * <p>
138          * Library sources are not supported in semantic version mode currently.
139          *
140          * @param libSources yang sources which should be added into library sources
141          * @return This build action, for fluent use.
142          */
143         public @NonNull BuildAction addLibSources(final StatementStreamSource... libSources) {
144             addLibSources(Arrays.asList(libSources));
145             return this;
146         }
147
148         public @NonNull BuildAction addLibSources(final Collection<StatementStreamSource> libSources) {
149             for (final StatementStreamSource libSource : libSources) {
150                 context.addLibSource(libSource);
151             }
152             return this;
153         }
154
155         /**
156          * Set supported features based on which all if-feature statements in the
157          * parsed YANG modules will be resolved.
158          *
159          * @param supportedFeatures
160          *            Set of supported features in the final SchemaContext.
161          *            If the set is empty, no features encountered will be supported.
162          * @return This build action, for fluent use.
163          */
164         public @NonNull BuildAction setSupportedFeatures(final @NonNull Set<QName> supportedFeatures) {
165             checkState(!supportedFeaturesSet, "Supported features should be set only once.");
166             context.setSupportedFeatures(requireNonNull(supportedFeatures));
167             supportedFeaturesSet = true;
168             return this;
169         }
170
171         /**
172          * Set YANG modules which can be deviated by specified modules during the parsing process.
173          * Map key (QNameModule) denotes a module which can be deviated by the modules in the Map value.
174          *
175          * @param modulesDeviatedByModules
176          *            Map of YANG modules (Map key) which can be deviated by specified modules (Map value) in the final
177          *            SchemaContext. If the map is empty, no deviations encountered will be supported.
178          * @return This build action, for fluent use.
179          */
180         public @NonNull BuildAction setModulesWithSupportedDeviations(
181                 final @NonNull SetMultimap<QNameModule, QNameModule> modulesDeviatedByModules) {
182             checkState(!modulesDeviatedByModulesSet, "Modules with supported deviations should be set only once.");
183             context.setModulesDeviatedByModules(requireNonNull(modulesDeviatedByModules));
184             modulesDeviatedByModulesSet = true;
185             return this;
186         }
187
188         /**
189          * Build the effective model context.
190          */
191         public EffectiveModelContext build() throws ReactorException {
192             return context.build();
193         }
194
195         public EffectiveSchemaContext buildEffective() throws ReactorException {
196             return context.buildEffective();
197         }
198     }
199 }