Move leaf-list statement implementations
[yangtools.git] / parser / yang-parser-rfc7950 / src / main / java / org / opendaylight / yangtools / yang / parser / rfc7950 / reactor / RFC7950Reactors.java
1 /*
2  * Copyright (c) 2017 Pantheon Technologies, s.r.o. 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.rfc7950.reactor;
9
10 import static org.opendaylight.yangtools.yang.common.YangVersion.VERSION_1;
11 import static org.opendaylight.yangtools.yang.common.YangVersion.VERSION_1_1;
12
13 import com.google.common.annotations.Beta;
14 import com.google.common.collect.ImmutableSet;
15 import com.google.common.collect.Sets;
16 import org.eclipse.jdt.annotation.NonNull;
17 import org.opendaylight.yangtools.yang.common.YangVersion;
18 import org.opendaylight.yangtools.yang.parser.api.YangParserConfiguration;
19 import org.opendaylight.yangtools.yang.parser.openconfig.stmt.OpenConfigVersionSupport;
20 import org.opendaylight.yangtools.yang.parser.rfc7950.namespace.ModuleQNameToPrefix;
21 import org.opendaylight.yangtools.yang.parser.rfc7950.namespace.YangNamespaceContextNamespace;
22 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.augment.AugmentImplicitHandlingNamespace;
23 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.augment.AugmentStatementRFC6020Support;
24 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.augment.AugmentStatementRFC7950Support;
25 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.deviate.DeviateStatementRFC6020Support;
26 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.deviate.DeviateStatementRFC7950Support;
27 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.extension.ExtensionStatementSupport;
28 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.if_feature.IfFeatureStatementRFC6020Support;
29 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.if_feature.IfFeatureStatementRFC7950Support;
30 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.import_.ImportStatementSupport;
31 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.import_.ImportedVersionNamespace;
32 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.list.ConfigListWarningNamespace;
33 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.list.ListStatementSupport;
34 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.meta.ActionStatementSupport;
35 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.meta.AnydataStatementSupport;
36 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.meta.AnyxmlStatementSupport;
37 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.meta.ArgumentStatementSupport;
38 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.meta.BaseStatementSupport;
39 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.meta.BelongsToStatementSupport;
40 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.meta.BitStatementSupport;
41 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.meta.CaseStatementSupport;
42 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.meta.ChoiceStatementSupport;
43 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.meta.ConfigStatementSupport;
44 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.meta.ContactStatementSupport;
45 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.meta.ContainerStatementSupport;
46 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.meta.DefaultStatementSupport;
47 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.meta.DescriptionStatementSupport;
48 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.meta.DeviationStatementSupport;
49 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.meta.EnumStatementSupport;
50 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.meta.ErrorAppTagStatementSupport;
51 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.meta.ErrorMessageStatementSupport;
52 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.meta.FeatureStatementSupport;
53 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.meta.FractionDigitsStatementSupport;
54 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.meta.GroupingStatementSupport;
55 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.meta.IdentityStatementSupport;
56 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.meta.IncludeStatementSupport;
57 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.meta.InputStatementSupport;
58 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.meta.KeyStatementSupport;
59 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.meta.LeafListStatementSupport;
60 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.meta.LeafStatementSupport;
61 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.meta.LengthStatementSupport;
62 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.meta.MandatoryStatementSupport;
63 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.meta.MaxElementsStatementSupport;
64 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.meta.MinElementsStatementSupport;
65 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.meta.ModifierStatementSupport;
66 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.meta.MustStatementSupport;
67 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.meta.NamespaceStatementSupport;
68 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.meta.OrderedByStatementSupport;
69 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.meta.OrganizationStatementSupport;
70 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.meta.OutputStatementSupport;
71 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.meta.PositionStatementSupport;
72 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.meta.PrefixStatementSupport;
73 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.meta.PresenceStatementSupport;
74 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.meta.RangeStatementSupport;
75 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.meta.ReferenceStatementSupport;
76 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.meta.RequireInstanceStatementSupport;
77 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.meta.RevisionDateStatementSupport;
78 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.meta.RevisionStatementSupport;
79 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.meta.RpcStatementSupport;
80 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.meta.StatusStatementSupport;
81 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.meta.TypedefStatementSupport;
82 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.meta.UniqueStatementSupport;
83 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.meta.UnitsStatementSupport;
84 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.meta.ValueStatementSupport;
85 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.meta.WhenStatementSupport;
86 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.meta.XPathSupport;
87 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.meta.YangVersionStatementSupport;
88 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.meta.YinElementStatementSupport;
89 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.module.ModuleStatementSupport;
90 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.module.QNameModuleNamespace;
91 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.notification.NotificationStatementRFC6020Support;
92 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.notification.NotificationStatementRFC7950Support;
93 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.path.PathStatementSupport;
94 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.pattern.PatternStatementSupport;
95 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.refine.RefineStatementSupport;
96 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.refine.RefineTargetNamespace;
97 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.submodule.SubmoduleStatementSupport;
98 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.type.BaseTypeNamespace;
99 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.type.TypeStatementRFC6020Support;
100 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.type.TypeStatementRFC7950Support;
101 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.uses.SourceGroupingNamespace;
102 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.uses.UsesStatementSupport;
103 import org.opendaylight.yangtools.yang.parser.spi.ExtensionNamespace;
104 import org.opendaylight.yangtools.yang.parser.spi.FeatureNamespace;
105 import org.opendaylight.yangtools.yang.parser.spi.GroupingNamespace;
106 import org.opendaylight.yangtools.yang.parser.spi.IdentityNamespace;
107 import org.opendaylight.yangtools.yang.parser.spi.ModuleNamespace;
108 import org.opendaylight.yangtools.yang.parser.spi.NamespaceToModule;
109 import org.opendaylight.yangtools.yang.parser.spi.PreLinkageModuleNamespace;
110 import org.opendaylight.yangtools.yang.parser.spi.SchemaTreeNamespace;
111 import org.opendaylight.yangtools.yang.parser.spi.SubmoduleNamespace;
112 import org.opendaylight.yangtools.yang.parser.spi.TypeNamespace;
113 import org.opendaylight.yangtools.yang.parser.spi.meta.ModelProcessingPhase;
114 import org.opendaylight.yangtools.yang.parser.spi.meta.SemanticVersionModuleNamespace;
115 import org.opendaylight.yangtools.yang.parser.spi.meta.SemanticVersionNamespace;
116 import org.opendaylight.yangtools.yang.parser.spi.meta.StatementDefinitionNamespace;
117 import org.opendaylight.yangtools.yang.parser.spi.meta.StatementSupportBundle;
118 import org.opendaylight.yangtools.yang.parser.spi.source.BelongsToModuleContext;
119 import org.opendaylight.yangtools.yang.parser.spi.source.BelongsToPrefixToModuleCtx;
120 import org.opendaylight.yangtools.yang.parser.spi.source.BelongsToPrefixToModuleName;
121 import org.opendaylight.yangtools.yang.parser.spi.source.ImpPrefixToNamespace;
122 import org.opendaylight.yangtools.yang.parser.spi.source.ImportPrefixToModuleCtx;
123 import org.opendaylight.yangtools.yang.parser.spi.source.ImportPrefixToSemVerSourceIdentifier;
124 import org.opendaylight.yangtools.yang.parser.spi.source.ImportedModuleContext;
125 import org.opendaylight.yangtools.yang.parser.spi.source.IncludedModuleContext;
126 import org.opendaylight.yangtools.yang.parser.spi.source.IncludedSubmoduleNameToModuleCtx;
127 import org.opendaylight.yangtools.yang.parser.spi.source.ModuleCtxToModuleQName;
128 import org.opendaylight.yangtools.yang.parser.spi.source.ModuleCtxToSourceIdentifier;
129 import org.opendaylight.yangtools.yang.parser.spi.source.ModuleNameToModuleQName;
130 import org.opendaylight.yangtools.yang.parser.spi.source.ModuleNameToNamespace;
131 import org.opendaylight.yangtools.yang.parser.spi.source.ModuleNamespaceForBelongsTo;
132 import org.opendaylight.yangtools.yang.parser.spi.source.ModuleQNameToModuleName;
133 import org.opendaylight.yangtools.yang.parser.spi.source.ModulesDeviatedByModules;
134 import org.opendaylight.yangtools.yang.parser.spi.source.PrefixToModule;
135 import org.opendaylight.yangtools.yang.parser.spi.source.SupportedFeaturesNamespace;
136 import org.opendaylight.yangtools.yang.parser.spi.validation.ValidationBundlesNamespace;
137 import org.opendaylight.yangtools.yang.parser.spi.validation.ValidationBundlesNamespace.ValidationBundleType;
138 import org.opendaylight.yangtools.yang.parser.stmt.reactor.CrossSourceStatementReactor;
139 import org.opendaylight.yangtools.yang.xpath.api.YangXPathParserFactory;
140
141 /**
142  * Utility class holding entrypoints for assembling RFC6020/RFC7950 statement {@link CrossSourceStatementReactor}s.
143  *
144  * @author Robert Varga
145  */
146 @Beta
147 public final class RFC7950Reactors {
148     private static final ImmutableSet<YangVersion> SUPPORTED_VERSIONS = Sets.immutableEnumSet(VERSION_1, VERSION_1_1);
149
150     private static final StatementSupportBundle INIT_BUNDLE = StatementSupportBundle.builder(SUPPORTED_VERSIONS)
151         .addSupport(ValidationBundlesNamespace.BEHAVIOUR)
152         .addSupport(SupportedFeaturesNamespace.BEHAVIOUR)
153         .addSupport(ModulesDeviatedByModules.BEHAVIOUR)
154         .build();
155
156     private RFC7950Reactors() {
157         // Hidden on purpose
158     }
159
160     private static StatementSupportBundle preLinkageBundle(final YangParserConfiguration config) {
161         return StatementSupportBundle.derivedFrom(INIT_BUNDLE)
162             .addVersionSpecificSupport(VERSION_1, ModuleStatementSupport.rfc6020Instance(config))
163             .addVersionSpecificSupport(VERSION_1_1, ModuleStatementSupport.rfc7950Instance(config))
164             .addVersionSpecificSupport(VERSION_1, SubmoduleStatementSupport.rfc6020Instance(config))
165             .addVersionSpecificSupport(VERSION_1_1, SubmoduleStatementSupport.rfc7950Instance(config))
166             .addSupport(new NamespaceStatementSupport(config))
167             .addVersionSpecificSupport(VERSION_1, ImportStatementSupport.rfc6020Instance(config))
168             .addVersionSpecificSupport(VERSION_1_1, ImportStatementSupport.rfc7950Instance(config))
169             .addVersionSpecificSupport(VERSION_1, IncludeStatementSupport.rfc6020Instance(config))
170             .addVersionSpecificSupport(VERSION_1_1, IncludeStatementSupport.rfc7950Instance(config))
171             .addSupport(new BelongsToStatementSupport(config))
172             .addSupport(new PrefixStatementSupport(config))
173             .addSupport(new YangVersionStatementSupport(config))
174             .addSupport(new RevisionStatementSupport(config))
175             .addSupport(new RevisionDateStatementSupport(config))
176             .addSupport(ModuleNameToNamespace.BEHAVIOUR)
177             .addSupport(PreLinkageModuleNamespace.BEHAVIOUR)
178             .addSupport(ImpPrefixToNamespace.BEHAVIOUR)
179             .addSupport(ModuleCtxToModuleQName.BEHAVIOUR)
180             .addSupport(QNameModuleNamespace.BEHAVIOUR)
181             .addSupport(ImportedVersionNamespace.BEHAVIOUR)
182             .build();
183     }
184
185     private static StatementSupportBundle linkageBundle(final StatementSupportBundle preLinkageBundle,
186             final YangParserConfiguration config) {
187         return StatementSupportBundle.derivedFrom(preLinkageBundle)
188             .addSupport(new DescriptionStatementSupport(config))
189             .addSupport(new ReferenceStatementSupport(config))
190             .addSupport(new ContactStatementSupport(config))
191             .addSupport(new OrganizationStatementSupport(config))
192             .addSupport(ModuleNamespace.BEHAVIOUR)
193             .addSupport(ModuleNamespaceForBelongsTo.BEHAVIOUR)
194             .addSupport(SubmoduleNamespace.BEHAVIOUR)
195             .addSupport(NamespaceToModule.BEHAVIOUR)
196             .addSupport(ModuleNameToModuleQName.BEHAVIOUR)
197             .addSupport(ModuleCtxToSourceIdentifier.BEHAVIOUR)
198             .addSupport(ModuleQNameToModuleName.BEHAVIOUR)
199             .addSupport(PrefixToModule.BEHAVIOUR)
200             .addSupport(ImportedModuleContext.BEHAVIOUR)
201             .addSupport(IncludedModuleContext.BEHAVIOUR)
202             .addSupport(IncludedSubmoduleNameToModuleCtx.BEHAVIOUR)
203             .addSupport(ImportPrefixToModuleCtx.BEHAVIOUR)
204             .addSupport(BelongsToPrefixToModuleCtx.BEHAVIOUR)
205             .addSupport(ModuleQNameToPrefix.BEHAVIOUR)
206             .addSupport(BelongsToModuleContext.BEHAVIOUR)
207             .addSupport(BelongsToPrefixToModuleName.BEHAVIOUR)
208             .build();
209     }
210
211     private static StatementSupportBundle stmtDefBundle(final StatementSupportBundle linkageBundle,
212             final YangParserConfiguration config) {
213         final InputStatementSupport rfc6020input = InputStatementSupport.rfc6020Instance(config);
214         final InputStatementSupport rfc7950input = InputStatementSupport.rfc7950Instance(config);
215         final OutputStatementSupport rfc6020output = OutputStatementSupport.rfc6020Instance(config);
216         final OutputStatementSupport rfc7950output = OutputStatementSupport.rfc7950Instance(config);
217
218         return StatementSupportBundle.derivedFrom(linkageBundle)
219             .addSupport(new YinElementStatementSupport(config))
220             .addSupport(new ArgumentStatementSupport(config))
221             .addSupport(new ExtensionStatementSupport(config))
222             .addSupport(SchemaTreeNamespace.getInstance())
223             .addSupport(ExtensionNamespace.BEHAVIOUR)
224             .addSupport(new TypedefStatementSupport(config))
225             .addSupport(TypeNamespace.BEHAVIOUR)
226             .addVersionSpecificSupport(VERSION_1, IdentityStatementSupport.rfc6020Instance(config))
227             .addVersionSpecificSupport(VERSION_1_1, IdentityStatementSupport.rfc7950Instance(config))
228             .addSupport(IdentityNamespace.BEHAVIOUR)
229             .addSupport(new DefaultStatementSupport(config))
230             .addSupport(new StatusStatementSupport(config))
231             .addSupport(BaseTypeNamespace.BEHAVIOUR)
232             .addVersionSpecificSupport(VERSION_1, new TypeStatementRFC6020Support(config))
233             .addVersionSpecificSupport(VERSION_1_1, new TypeStatementRFC7950Support(config))
234             .addSupport(new UnitsStatementSupport(config))
235             .addSupport(new RequireInstanceStatementSupport(config))
236             .addVersionSpecificSupport(VERSION_1, BitStatementSupport.rfc6020Instance(config))
237             .addVersionSpecificSupport(VERSION_1_1, BitStatementSupport.rfc7950Instance(config))
238             .addSupport(PathStatementSupport.strictInstance(config))
239             .addVersionSpecificSupport(VERSION_1, EnumStatementSupport.rfc6020Instance(config))
240             .addVersionSpecificSupport(VERSION_1_1, EnumStatementSupport.rfc7950Instance(config))
241             .addSupport(new LengthStatementSupport(config))
242             .addVersionSpecificSupport(VERSION_1, PatternStatementSupport.rfc6020Instance(config))
243             .addVersionSpecificSupport(VERSION_1_1, PatternStatementSupport.rfc7950Instance(config))
244             .addVersionSpecificSupport(VERSION_1_1, new ModifierStatementSupport(config))
245             .addSupport(new RangeStatementSupport(config))
246             .addSupport(new KeyStatementSupport(config))
247             .addVersionSpecificSupport(VERSION_1, ContainerStatementSupport.rfc6020Instance(config))
248             .addVersionSpecificSupport(VERSION_1_1, ContainerStatementSupport.rfc7950Instance(config))
249             .addVersionSpecificSupport(VERSION_1, GroupingStatementSupport.rfc6020Instance(config))
250             .addVersionSpecificSupport(VERSION_1_1, GroupingStatementSupport.rfc7950Instance(config))
251             .addVersionSpecificSupport(VERSION_1, ListStatementSupport.rfc6020Instance(config))
252             .addVersionSpecificSupport(VERSION_1_1, ListStatementSupport.rfc7950Instance(config))
253             .addSupport(ConfigListWarningNamespace.BEHAVIOUR)
254             .addSupport(new UniqueStatementSupport(config))
255             .addVersionSpecificSupport(VERSION_1_1, new ActionStatementSupport(config, rfc7950input, rfc7950output))
256             .addVersionSpecificSupport(VERSION_1, new RpcStatementSupport(config, rfc6020input, rfc6020output))
257             .addVersionSpecificSupport(VERSION_1_1, new RpcStatementSupport(config, rfc7950input, rfc7950output))
258             .addVersionSpecificSupport(VERSION_1, rfc6020input)
259             .addVersionSpecificSupport(VERSION_1_1, rfc7950input)
260             .addVersionSpecificSupport(VERSION_1, rfc6020output)
261             .addVersionSpecificSupport(VERSION_1_1, rfc7950output)
262             .addVersionSpecificSupport(VERSION_1, new NotificationStatementRFC6020Support(config))
263             .addVersionSpecificSupport(VERSION_1_1, new NotificationStatementRFC7950Support(config))
264             .addSupport(new FractionDigitsStatementSupport(config))
265             .addSupport(new BaseStatementSupport(config))
266             .addSupport(StatementDefinitionNamespace.BEHAVIOUR)
267             .build();
268     }
269
270     /**
271      * Returns a pre-built {@link CrossSourceStatementReactor} supporting RFC6020 and RFC7950, along with OpenConfig
272      * semantic version extension. This is useful for parsing near-vanilla YANG models while providing complete
273      * support for semantic versions.
274      *
275      * @return A shared reactor instance.
276      */
277     public static @NonNull CrossSourceStatementReactor defaultReactor() {
278         return ServiceLoaderState.DefaultReactor.INSTANCE;
279     }
280
281     /**
282      * Returns a partially-configured {@link CustomCrossSourceStatementReactorBuilder}, with RFC6020/RFC7950
283      * and OpenConfig semantic version support enabled.
284      *
285      * @return A new {@link CustomCrossSourceStatementReactorBuilder}.
286      */
287     public static @NonNull CustomCrossSourceStatementReactorBuilder defaultReactorBuilder() {
288         return defaultReactorBuilder(YangParserConfiguration.DEFAULT);
289     }
290
291     public static @NonNull CustomCrossSourceStatementReactorBuilder defaultReactorBuilder(
292             final YangParserConfiguration config) {
293         return addExtensions(vanillaReactorBuilder(config), config);
294     }
295
296     public static @NonNull CustomCrossSourceStatementReactorBuilder defaultReactorBuilder(
297             final YangXPathParserFactory xpathFactory) {
298         return defaultReactorBuilder(xpathFactory, YangParserConfiguration.DEFAULT);
299     }
300
301     public static @NonNull CustomCrossSourceStatementReactorBuilder defaultReactorBuilder(
302             final YangXPathParserFactory xpathFactory, final YangParserConfiguration config) {
303         return addExtensions(vanillaReactorBuilder(xpathFactory, config), config);
304     }
305
306     private static @NonNull CustomCrossSourceStatementReactorBuilder addExtensions(
307             final @NonNull CustomCrossSourceStatementReactorBuilder builder, final YangParserConfiguration config) {
308         return builder
309                 // Semantic version support
310                 .addStatementSupport(ModelProcessingPhase.SOURCE_LINKAGE, new OpenConfigVersionSupport(config))
311                 .addNamespaceSupport(ModelProcessingPhase.SOURCE_LINKAGE, SemanticVersionNamespace.BEHAVIOUR)
312                 .addNamespaceSupport(ModelProcessingPhase.SOURCE_LINKAGE, SemanticVersionModuleNamespace.BEHAVIOUR)
313                 .addNamespaceSupport(ModelProcessingPhase.SOURCE_LINKAGE,
314                     ImportPrefixToSemVerSourceIdentifier.BEHAVIOUR);
315     }
316
317     /**
318      * Returns a pre-built {@link CrossSourceStatementReactor} supporting both RFC6020 and RFC7950. This is useful
319      * for parsing vanilla YANG models without any semantic support for extensions. Notably missing is the semantic
320      * version extension, hence attempts to use semantic version mode will cause failures.
321      *
322      * @return A shared reactor instance.
323      */
324     public static @NonNull CrossSourceStatementReactor vanillaReactor() {
325         return ServiceLoaderState.VanillaReactor.INSTANCE;
326     }
327
328     /**
329      * Returns a partially-configured {@link CustomCrossSourceStatementReactorBuilder}, with vanilla RFC6020/RFC7950
330      * support enabled.
331      *
332      * @return A new {@link CustomCrossSourceStatementReactorBuilder}.
333      */
334     public static @NonNull CustomCrossSourceStatementReactorBuilder vanillaReactorBuilder() {
335         return vanillaReactorBuilder(YangParserConfiguration.DEFAULT);
336     }
337
338     public static @NonNull CustomCrossSourceStatementReactorBuilder vanillaReactorBuilder(
339             final YangParserConfiguration config) {
340         return vanillaReactorBuilder(ServiceLoaderState.XPath.INSTANCE, config);
341     }
342
343     public static @NonNull CustomCrossSourceStatementReactorBuilder vanillaReactorBuilder(
344             final @NonNull YangXPathParserFactory xpathFactory) {
345         return vanillaReactorBuilder(xpathFactory, YangParserConfiguration.DEFAULT);
346     }
347
348     public static @NonNull CustomCrossSourceStatementReactorBuilder vanillaReactorBuilder(
349             final @NonNull YangXPathParserFactory xpathFactory, final YangParserConfiguration config) {
350         return vanillaReactorBuilder(new XPathSupport(xpathFactory), config);
351     }
352
353     private static @NonNull CustomCrossSourceStatementReactorBuilder vanillaReactorBuilder(
354             final @NonNull XPathSupport xpathSupport, final YangParserConfiguration config) {
355         final StatementSupportBundle preLinkageBundle = preLinkageBundle(config);
356         final StatementSupportBundle linkageBundle = linkageBundle(preLinkageBundle, config);
357         final StatementSupportBundle stmtDefBundle = stmtDefBundle(linkageBundle, config);
358         final StatementSupportBundle fullDeclarationBundle =
359             fullDeclarationBundle(stmtDefBundle, xpathSupport, config);
360
361         return new CustomCrossSourceStatementReactorBuilder(SUPPORTED_VERSIONS)
362                 .addAllSupports(ModelProcessingPhase.INIT, INIT_BUNDLE)
363                 .addAllSupports(ModelProcessingPhase.SOURCE_PRE_LINKAGE, preLinkageBundle)
364                 .addAllSupports(ModelProcessingPhase.SOURCE_LINKAGE, linkageBundle)
365                 .addAllSupports(ModelProcessingPhase.STATEMENT_DEFINITION, stmtDefBundle)
366                 .addAllSupports(ModelProcessingPhase.FULL_DECLARATION, fullDeclarationBundle)
367                 .addAllSupports(ModelProcessingPhase.EFFECTIVE_MODEL, fullDeclarationBundle)
368                 .addValidationBundle(ValidationBundleType.SUPPORTED_REFINE_SUBSTATEMENTS,
369                     YangValidationBundles.SUPPORTED_REFINE_SUBSTATEMENTS)
370                 .addValidationBundle(ValidationBundleType.SUPPORTED_AUGMENT_TARGETS,
371                     YangValidationBundles.SUPPORTED_AUGMENT_TARGETS)
372
373                 // FIXME: 7.0.0: we do not seem to need this validation bundle
374                 .addValidationBundle(ValidationBundleType.SUPPORTED_CASE_SHORTHANDS,
375                     YangValidationBundles.SUPPORTED_CASE_SHORTHANDS)
376
377                 .addValidationBundle(ValidationBundleType.SUPPORTED_DATA_NODES,
378                     YangValidationBundles.SUPPORTED_DATA_NODES);
379     }
380
381     private static @NonNull StatementSupportBundle fullDeclarationBundle(final StatementSupportBundle stmtDefBundle,
382             final XPathSupport xpathSupport, final YangParserConfiguration config) {
383         final CaseStatementSupport rfc6020case = CaseStatementSupport.rfc6020Instance(config);
384         final CaseStatementSupport rfc7950case = CaseStatementSupport.rfc7950Instance(config);
385
386         return StatementSupportBundle.derivedFrom(stmtDefBundle)
387             .addSupport(new LeafStatementSupport(config))
388             .addSupport(new ConfigStatementSupport(config))
389             .addSupport(new DeviationStatementSupport(config))
390             .addVersionSpecificSupport(VERSION_1, new DeviateStatementRFC6020Support(config))
391             .addVersionSpecificSupport(VERSION_1_1, new DeviateStatementRFC7950Support(config))
392             .addVersionSpecificSupport(VERSION_1, ChoiceStatementSupport.rfc6020Instance(config, rfc6020case))
393             .addVersionSpecificSupport(VERSION_1_1, ChoiceStatementSupport.rfc7950Instance(config, rfc7950case))
394             .addVersionSpecificSupport(VERSION_1, rfc6020case)
395             .addVersionSpecificSupport(VERSION_1_1, rfc7950case)
396             .addSupport(new MustStatementSupport(xpathSupport, config))
397             .addSupport(new MandatoryStatementSupport(config))
398             .addSupport(new AnyxmlStatementSupport(config))
399             .addVersionSpecificSupport(VERSION_1_1, new AnydataStatementSupport(config))
400             .addSupport(FeatureNamespace.BEHAVIOUR)
401             .addVersionSpecificSupport(VERSION_1, new IfFeatureStatementRFC6020Support(config))
402             .addVersionSpecificSupport(VERSION_1_1, new IfFeatureStatementRFC7950Support(config))
403             .addSupport(GroupingNamespace.BEHAVIOUR)
404             .addSupport(SourceGroupingNamespace.BEHAVIOUR)
405             .addSupport(new UsesStatementSupport(config))
406             .addSupport(new ErrorMessageStatementSupport(config))
407             .addSupport(new ErrorAppTagStatementSupport(config))
408             .addVersionSpecificSupport(VERSION_1, LeafListStatementSupport.rfc6020Instance(config))
409             .addVersionSpecificSupport(VERSION_1_1, LeafListStatementSupport.rfc7950Instance(config))
410             .addSupport(new PresenceStatementSupport(config))
411             .addSupport(new MaxElementsStatementSupport(config))
412             .addSupport(new MinElementsStatementSupport(config))
413             .addSupport(new OrderedByStatementSupport(config))
414             .addSupport(new WhenStatementSupport(xpathSupport, config))
415             .addSupport(AugmentImplicitHandlingNamespace.BEHAVIOUR)
416             .addVersionSpecificSupport(VERSION_1, new AugmentStatementRFC6020Support(config))
417             .addVersionSpecificSupport(VERSION_1_1, new AugmentStatementRFC7950Support(config))
418             .addSupport(RefineTargetNamespace.BEHAVIOUR)
419             .addVersionSpecificSupport(VERSION_1, RefineStatementSupport.rfc6020Instance(config))
420             .addVersionSpecificSupport(VERSION_1_1, RefineStatementSupport.rfc7950Instance(config))
421             .addSupport(new FeatureStatementSupport(config))
422             .addSupport(new PositionStatementSupport(config))
423             .addSupport(new ValueStatementSupport(config))
424             .addSupport(YangNamespaceContextNamespace.BEHAVIOUR)
425             .build();
426     }
427 }