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