Verify map lookups
[yangtools.git] / parser / yang-parser-rfc7950 / src / main / java / org / opendaylight / yangtools / yang / parser / rfc7950 / reactor / CustomCrossSourceStatementReactorBuilder.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.rfc7950.reactor;
9
10 import static com.google.common.base.Verify.verifyNotNull;
11
12 import com.google.common.annotations.Beta;
13 import com.google.common.collect.ImmutableMap;
14 import com.google.common.collect.Table;
15 import com.google.common.collect.Table.Cell;
16 import java.util.Collection;
17 import java.util.HashMap;
18 import java.util.Map;
19 import java.util.Map.Entry;
20 import java.util.Set;
21 import org.eclipse.jdt.annotation.NonNull;
22 import org.opendaylight.yangtools.concepts.Mutable;
23 import org.opendaylight.yangtools.yang.common.QName;
24 import org.opendaylight.yangtools.yang.common.YangVersion;
25 import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
26 import org.opendaylight.yangtools.yang.parser.spi.meta.ModelProcessingPhase;
27 import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour;
28 import org.opendaylight.yangtools.yang.parser.spi.meta.StatementSupport;
29 import org.opendaylight.yangtools.yang.parser.spi.meta.StatementSupportBundle;
30 import org.opendaylight.yangtools.yang.parser.spi.validation.ValidationBundlesNamespace.ValidationBundleType;
31 import org.opendaylight.yangtools.yang.parser.stmt.reactor.CrossSourceStatementReactor;
32
33 @Beta
34 public class CustomCrossSourceStatementReactorBuilder implements Mutable {
35     private final ImmutableMap<ModelProcessingPhase, StatementSupportBundle.Builder> reactorSupportBundles;
36     private final Map<ValidationBundleType, Collection<StatementDefinition>> reactorValidationBundles = new HashMap<>();
37
38     /**
39      * Creates a new CustomCrossSourceStatementReactorBuilder object initialized by specific version bundle. Statement
40      * parser will support all versions defined in given version bundle.
41      *
42      * @param supportedVersions
43      *            bundle of supported verions
44      */
45     CustomCrossSourceStatementReactorBuilder(final Set<YangVersion> supportedVersions) {
46         reactorSupportBundles = ImmutableMap.<ModelProcessingPhase, StatementSupportBundle.Builder>builder()
47                 .put(ModelProcessingPhase.INIT, StatementSupportBundle.builder(supportedVersions))
48                 .put(ModelProcessingPhase.SOURCE_PRE_LINKAGE, StatementSupportBundle.builder(supportedVersions))
49                 .put(ModelProcessingPhase.SOURCE_LINKAGE, StatementSupportBundle.builder(supportedVersions))
50                 .put(ModelProcessingPhase.STATEMENT_DEFINITION, StatementSupportBundle.builder(supportedVersions))
51                 .put(ModelProcessingPhase.FULL_DECLARATION, StatementSupportBundle.builder(supportedVersions))
52                 .put(ModelProcessingPhase.EFFECTIVE_MODEL, StatementSupportBundle.builder(supportedVersions)).build();
53     }
54
55     public @NonNull CustomCrossSourceStatementReactorBuilder addStatementSupport(final ModelProcessingPhase phase,
56             final StatementSupport<?, ?, ?> stmtSupport) {
57         getBuilder(phase).addSupport(stmtSupport);
58         return this;
59     }
60
61     public @NonNull CustomCrossSourceStatementReactorBuilder overrideStatementSupport(final ModelProcessingPhase phase,
62             final StatementSupport<?, ?, ?> stmtSupport) {
63         getBuilder(phase).overrideSupport(stmtSupport);
64         return this;
65     }
66
67     public @NonNull CustomCrossSourceStatementReactorBuilder addNamespaceSupport(final ModelProcessingPhase phase,
68             final NamespaceBehaviour<?, ?, ?> namespaceSupport) {
69         getBuilder(phase).addSupport(namespaceSupport);
70         return this;
71     }
72
73     public @NonNull CustomCrossSourceStatementReactorBuilder addValidationBundle(
74             final ValidationBundleType validationBundleType, final Collection<StatementDefinition> validationBundle) {
75         reactorValidationBundles.put(validationBundleType, validationBundle);
76         return this;
77     }
78
79     public @NonNull CustomCrossSourceStatementReactorBuilder addAllSupports(final ModelProcessingPhase phase,
80             final StatementSupportBundle stmtSupportBundle) {
81         addAllCommonStatementSupports(phase, stmtSupportBundle.getCommonDefinitions().values());
82         addAllVersionSpecificSupports(phase, stmtSupportBundle.getAllVersionSpecificDefinitions());
83         addAllNamespaceSupports(phase, stmtSupportBundle.getNamespaceDefinitions().values());
84         return this;
85     }
86
87     public @NonNull CustomCrossSourceStatementReactorBuilder addAllNamespaceSupports(final ModelProcessingPhase phase,
88             final Collection<NamespaceBehaviour<?, ?, ?>> namespaceSupports) {
89         final StatementSupportBundle.Builder stmtBundleBuilder = reactorSupportBundles.get(phase);
90         for (final NamespaceBehaviour<?, ?, ?> namespaceSupport : namespaceSupports) {
91             stmtBundleBuilder.addSupport(namespaceSupport);
92         }
93         return this;
94     }
95
96     public @NonNull CustomCrossSourceStatementReactorBuilder addAllCommonStatementSupports(
97             final ModelProcessingPhase phase, final Collection<StatementSupport<?, ?, ?>> statementSupports) {
98         final StatementSupportBundle.Builder stmtBundleBuilder = reactorSupportBundles.get(phase);
99         for (final StatementSupport<?, ?, ?> statementSupport : statementSupports) {
100             stmtBundleBuilder.addSupport(statementSupport);
101         }
102         return this;
103     }
104
105     public @NonNull CustomCrossSourceStatementReactorBuilder addAllVersionSpecificSupports(
106             final ModelProcessingPhase phase,
107             final Table<YangVersion, QName, StatementSupport<?, ?, ?>> versionSpecificSupports) {
108         final StatementSupportBundle.Builder stmtBundleBuilder = reactorSupportBundles.get(phase);
109         for (final Cell<YangVersion, QName, StatementSupport<?, ?, ?>> cell : versionSpecificSupports.cellSet()) {
110             stmtBundleBuilder.addVersionSpecificSupport(cell.getRowKey(), cell.getValue());
111         }
112         return this;
113     }
114
115     /**
116      * Return a new {@link CrossSourceStatementReactor}.
117      *
118      * @return A CrossSourceStatementReactor
119      */
120     public @NonNull CrossSourceStatementReactor build() {
121         final StatementSupportBundle initBundle = getBuilder(ModelProcessingPhase.INIT).build();
122         final StatementSupportBundle preLinkageBundle = getBuilder(ModelProcessingPhase.SOURCE_PRE_LINKAGE)
123             .setParent(initBundle).build();
124         final StatementSupportBundle linkageBundle = getBuilder(ModelProcessingPhase.SOURCE_LINKAGE)
125             .setParent(preLinkageBundle).build();
126         final StatementSupportBundle stmtDefBundle = getBuilder(ModelProcessingPhase.STATEMENT_DEFINITION)
127             .setParent(linkageBundle).build();
128         final StatementSupportBundle fullDeclBundle = getBuilder(ModelProcessingPhase.FULL_DECLARATION)
129             .setParent(stmtDefBundle).build();
130         final StatementSupportBundle effectiveBundle = getBuilder(ModelProcessingPhase.EFFECTIVE_MODEL)
131             .setParent(fullDeclBundle).build();
132
133         final CrossSourceStatementReactor.Builder reactorBuilder = CrossSourceStatementReactor.builder()
134                 .setBundle(ModelProcessingPhase.INIT, initBundle)
135                 .setBundle(ModelProcessingPhase.SOURCE_PRE_LINKAGE, preLinkageBundle)
136                 .setBundle(ModelProcessingPhase.SOURCE_LINKAGE, linkageBundle)
137                 .setBundle(ModelProcessingPhase.STATEMENT_DEFINITION, stmtDefBundle)
138                 .setBundle(ModelProcessingPhase.FULL_DECLARATION, fullDeclBundle)
139                 .setBundle(ModelProcessingPhase.EFFECTIVE_MODEL, effectiveBundle);
140
141         for (Entry<ValidationBundleType, Collection<StatementDefinition>> entry : reactorValidationBundles.entrySet()) {
142             reactorBuilder.setValidationBundle(entry.getKey(), entry.getValue());
143         }
144
145         return reactorBuilder.build();
146     }
147
148     private StatementSupportBundle.@NonNull Builder getBuilder(final ModelProcessingPhase phase) {
149         return verifyNotNull(reactorSupportBundles.get(phase));
150     }
151 }