Bug 6551: Support for third-party Yang extensions implementation
[yangtools.git] / yang / yang-parser-impl / src / main / java / org / opendaylight / yangtools / yang / parser / stmt / reactor / CustomStatementParserBuilder.java
1 /*
2  * Copyright (c) 2016 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.collect.ImmutableMap;
11 import java.util.Collection;
12 import java.util.HashMap;
13 import java.util.Map;
14 import java.util.Map.Entry;
15 import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
16 import org.opendaylight.yangtools.yang.parser.spi.meta.ModelProcessingPhase;
17 import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour;
18 import org.opendaylight.yangtools.yang.parser.spi.meta.StatementSupport;
19 import org.opendaylight.yangtools.yang.parser.spi.meta.StatementSupportBundle;
20 import org.opendaylight.yangtools.yang.parser.spi.validation.ValidationBundlesNamespace.ValidationBundleType;
21 import org.opendaylight.yangtools.yang.parser.stmt.reactor.CrossSourceStatementReactor.Builder;
22 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.YangInferencePipeline;
23
24 public class CustomStatementParserBuilder {
25     private final Map<ModelProcessingPhase, StatementSupportBundle.Builder> reactorSupportBundles = ImmutableMap
26             .<ModelProcessingPhase, StatementSupportBundle.Builder> builder()
27             .put(ModelProcessingPhase.INIT, StatementSupportBundle.builder())
28             .put(ModelProcessingPhase.SOURCE_PRE_LINKAGE, StatementSupportBundle.builder())
29             .put(ModelProcessingPhase.SOURCE_LINKAGE, StatementSupportBundle.builder())
30             .put(ModelProcessingPhase.STATEMENT_DEFINITION, StatementSupportBundle.builder())
31             .put(ModelProcessingPhase.FULL_DECLARATION, StatementSupportBundle.builder())
32             .put(ModelProcessingPhase.EFFECTIVE_MODEL, StatementSupportBundle.builder()).build();
33     private final Map<ValidationBundleType, Collection<StatementDefinition>> reactorValidationBundles = new HashMap<>();
34
35     public CustomStatementParserBuilder addStatementSupport(final ModelProcessingPhase phase,
36             final StatementSupport<?, ?, ?> stmtSupport) {
37         reactorSupportBundles.get(phase).addSupport(stmtSupport);
38         return this;
39     }
40
41     public CustomStatementParserBuilder addNamespaceSupport(final ModelProcessingPhase phase,
42             final NamespaceBehaviour<?, ?, ?> namespaceSupport) {
43         reactorSupportBundles.get(phase).addSupport(namespaceSupport);
44         return this;
45     }
46
47     public CustomStatementParserBuilder addDefaultRFC6020Bundles() {
48         addRFC6020SupportBundles();
49         addRFC6020ValidationBundles();
50         return this;
51     }
52
53     private void addRFC6020ValidationBundles() {
54         reactorValidationBundles.putAll(YangInferencePipeline.RFC6020_VALIDATION_BUNDLE);
55     }
56
57     private void addRFC6020SupportBundles() {
58         for (final Entry<ModelProcessingPhase, StatementSupportBundle> entry : YangInferencePipeline.RFC6020_BUNDLES
59                 .entrySet()) {
60             addAllSupports(entry.getKey(), entry.getValue());
61         }
62     }
63
64     public CustomStatementParserBuilder addValidationBundle(final ValidationBundleType validationBundleType,
65             final Collection<StatementDefinition> validationBundle) {
66         reactorValidationBundles.put(validationBundleType, validationBundle);
67         return this;
68     }
69
70     public CustomStatementParserBuilder addAllSupports(final ModelProcessingPhase phase,
71             final StatementSupportBundle stmtSupportBundle) {
72         addAllStatementSupports(phase, stmtSupportBundle.getDefinitions().values());
73         addAllNamespaceSupports(phase, stmtSupportBundle.getNamespaceDefinitions().values());
74         return this;
75     }
76
77     public CustomStatementParserBuilder addAllNamespaceSupports(final ModelProcessingPhase phase,
78             final Collection<NamespaceBehaviour<?, ?, ?>> namespaceSupports) {
79         final StatementSupportBundle.Builder stmtBundleBuilder = reactorSupportBundles.get(phase);
80         for (final NamespaceBehaviour<?, ?, ?> namespaceSupport : namespaceSupports) {
81             stmtBundleBuilder.addSupport(namespaceSupport);
82         }
83         return this;
84     }
85
86     public CustomStatementParserBuilder addAllStatementSupports(final ModelProcessingPhase phase,
87             final Collection<StatementSupport<?, ?, ?>> statementSupports) {
88         final StatementSupportBundle.Builder stmtBundleBuilder = reactorSupportBundles.get(phase);
89         for (final StatementSupport<?, ?, ?> statementSupport : statementSupports) {
90             stmtBundleBuilder.addSupport(statementSupport);
91         }
92         return this;
93     }
94
95     public CrossSourceStatementReactor build() {
96         final StatementSupportBundle initBundle = reactorSupportBundles.get(ModelProcessingPhase.INIT).build();
97         final StatementSupportBundle preLinkageBundle = reactorSupportBundles
98                 .get(ModelProcessingPhase.SOURCE_PRE_LINKAGE).setParent(initBundle).build();
99         final StatementSupportBundle linkageBundle = reactorSupportBundles.get(ModelProcessingPhase.SOURCE_LINKAGE)
100                 .setParent(preLinkageBundle).build();
101         final StatementSupportBundle stmtDefBundle = reactorSupportBundles
102                 .get(ModelProcessingPhase.STATEMENT_DEFINITION).setParent(linkageBundle).build();
103         final StatementSupportBundle fullDeclBundle = reactorSupportBundles.get(ModelProcessingPhase.FULL_DECLARATION)
104                 .setParent(stmtDefBundle).build();
105         final StatementSupportBundle effectiveBundle = reactorSupportBundles.get(ModelProcessingPhase.EFFECTIVE_MODEL)
106                 .setParent(fullDeclBundle).build();
107
108         final Builder reactorBuilder = CrossSourceStatementReactor.builder()
109                 .setBundle(ModelProcessingPhase.INIT, initBundle)
110                 .setBundle(ModelProcessingPhase.SOURCE_PRE_LINKAGE, preLinkageBundle)
111                 .setBundle(ModelProcessingPhase.SOURCE_LINKAGE, linkageBundle)
112                 .setBundle(ModelProcessingPhase.STATEMENT_DEFINITION, stmtDefBundle)
113                 .setBundle(ModelProcessingPhase.FULL_DECLARATION, fullDeclBundle)
114                 .setBundle(ModelProcessingPhase.EFFECTIVE_MODEL, effectiveBundle);
115
116         for (final Entry<ValidationBundleType, Collection<StatementDefinition>> entry : reactorValidationBundles
117                 .entrySet()) {
118             reactorBuilder.setValidationBundle(entry.getKey(), entry.getValue());
119         }
120
121         return reactorBuilder.build();
122     }
123 }