Disconnect CrossSourceStatementReactor.Builder
[yangtools.git] / parser / 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.concepts.Mutable;
22 import org.opendaylight.yangtools.yang.common.QName;
23 import org.opendaylight.yangtools.yang.common.QNameModule;
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 ImmutableMap<ModelProcessingPhase, StatementSupportBundle> supportedTerminology;
32     private final ImmutableMap<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 new BuildAction(supportedTerminology, supportedValidation);
56     }
57
58     public static class Builder implements Mutable {
59         private final Map<ValidationBundleType, Collection<?>> validationBundles =
60                 new EnumMap<>(ValidationBundleType.class);
61         private final Map<ModelProcessingPhase, StatementSupportBundle> bundles =
62                 new EnumMap<>(ModelProcessingPhase.class);
63
64         public @NonNull Builder setBundle(final ModelProcessingPhase phase, final StatementSupportBundle bundle) {
65             bundles.put(phase, bundle);
66             return this;
67         }
68
69         public @NonNull Builder setValidationBundle(final ValidationBundleType type,
70                 final Collection<?> validationBundle) {
71             validationBundles.put(type, validationBundle);
72             return this;
73         }
74
75         /**
76          * Return a {@link CrossSourceStatementReactor} configured with current state of this builder.
77          *
78          * @return A CrossSourceStatementReactor
79          */
80         public @NonNull CrossSourceStatementReactor build() {
81             return new CrossSourceStatementReactor(bundles, validationBundles);
82         }
83     }
84
85     public static class BuildAction {
86         private final BuildGlobalContext context;
87         private boolean supportedFeaturesSet = false;
88         private boolean modulesDeviatedByModulesSet = false;
89
90         BuildAction(final ImmutableMap<ModelProcessingPhase, StatementSupportBundle> supportedTerminology,
91                 final ImmutableMap<ValidationBundleType, Collection<?>> supportedValidation) {
92             context = new BuildGlobalContext(supportedTerminology, supportedValidation);
93         }
94
95         /**
96          * Add main source. All main sources are present in resulting SchemaContext.
97          *
98          * @param source which should be added into main sources
99          * @return This build action, for fluent use.
100          * @throws NullPointerException if @{code source} is null
101          */
102         public @NonNull BuildAction addSource(final StatementStreamSource source) {
103             context.addSource(source);
104             return this;
105         }
106
107         /**
108          * Add main sources. All main sources are present in resulting SchemaContext.
109          *
110          * @param sources which should be added into main sources
111          * @return This build action, for fluent use.
112          * @throws NullPointerException if @{code sources} is null or contains a null element
113          */
114         public @NonNull BuildAction addSources(final StatementStreamSource... sources) {
115             addSources(Arrays.asList(sources));
116             return this;
117         }
118
119         /**
120          * Add main sources. All main sources are present in resulting SchemaContext.
121          *
122          * @param sources which should be added into main sources
123          * @return This build action, for fluent use.
124          * @throws NullPointerException if @{code sources} is null or contains a null element
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 a library source. 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 libSource source which should be added into library sources
141          * @return This build action, for fluent use.
142          * @throws NullPointerException if @{code libSource} is null
143          */
144         public @NonNull BuildAction addLibSource(final StatementStreamSource libSource) {
145             context.addLibSource(libSource);
146             return this;
147         }
148
149         /**
150          * Add library sources. Only library sources required by main sources are present in resulting SchemaContext.
151          * Any other library sources are ignored and this also applies to error reporting.
152          *
153          * <p>
154          * Library sources are not supported in semantic version mode currently.
155          *
156          * @param libSources sources which should be added into library sources
157          * @return This build action, for fluent use.
158          * @throws NullPointerException if @{code libSources} is null or contains a null element
159          */
160         public @NonNull BuildAction addLibSources(final StatementStreamSource... libSources) {
161             addLibSources(Arrays.asList(libSources));
162             return this;
163         }
164
165         /**
166          * Add library sources. Only library sources required by main sources are present in resulting SchemaContext.
167          * Any other library sources are ignored and this also applies to error reporting.
168          *
169          * <p>
170          * Library sources are not supported in semantic version mode currently.
171          *
172          * @param libSources sources which should be added into library sources
173          * @return This build action, for fluent use.
174          * @throws NullPointerException if @{code libSources} is null or contains a null element
175          */
176         public @NonNull BuildAction addLibSources(final Collection<StatementStreamSource> libSources) {
177             for (final StatementStreamSource libSource : libSources) {
178                 context.addLibSource(libSource);
179             }
180             return this;
181         }
182
183         /**
184          * Set supported features based on which all if-feature statements in the
185          * parsed YANG modules will be resolved.
186          *
187          * @param supportedFeatures
188          *            Set of supported features in the final SchemaContext.
189          *            If the set is empty, no features encountered will be supported.
190          * @return This build action, for fluent use.
191          */
192         public @NonNull BuildAction setSupportedFeatures(final @NonNull Set<QName> supportedFeatures) {
193             checkState(!supportedFeaturesSet, "Supported features should be set only once.");
194             context.setSupportedFeatures(requireNonNull(supportedFeatures));
195             supportedFeaturesSet = true;
196             return this;
197         }
198
199         /**
200          * Set YANG modules which can be deviated by specified modules during the parsing process.
201          * Map key (QNameModule) denotes a module which can be deviated by the modules in the Map value.
202          *
203          * @param modulesDeviatedByModules
204          *            Map of YANG modules (Map key) which can be deviated by specified modules (Map value) in the final
205          *            SchemaContext. If the map is empty, no deviations encountered will be supported.
206          * @return This build action, for fluent use.
207          */
208         public @NonNull BuildAction setModulesWithSupportedDeviations(
209                 final @NonNull SetMultimap<QNameModule, QNameModule> modulesDeviatedByModules) {
210             checkState(!modulesDeviatedByModulesSet, "Modules with supported deviations should be set only once.");
211             context.setModulesDeviatedByModules(requireNonNull(modulesDeviatedByModules));
212             modulesDeviatedByModulesSet = true;
213             return this;
214         }
215
216         /**
217          * Build the effective model context.
218          */
219         public ReactorDeclaredModel build() throws ReactorException {
220             return context.build();
221         }
222
223         public EffectiveSchemaContext buildEffective() throws ReactorException {
224             return context.buildEffective();
225         }
226     }
227 }