Promote FeatureSet
[yangtools.git] / parser / yang-parser-impl / src / main / java / org / opendaylight / yangtools / yang / parser / impl / DefaultYangParser.java
1 /*
2  * Copyright (c) 2021 PANTHEON.tech, 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.impl;
9
10 import static java.util.Objects.requireNonNull;
11
12 import com.google.common.collect.ImmutableList;
13 import com.google.common.collect.SetMultimap;
14 import java.io.IOException;
15 import java.util.Collection;
16 import java.util.List;
17 import javax.xml.transform.TransformerException;
18 import org.eclipse.jdt.annotation.NonNull;
19 import org.opendaylight.yangtools.yang.common.QNameModule;
20 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
21 import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
22 import org.opendaylight.yangtools.yang.model.api.stmt.FeatureSet;
23 import org.opendaylight.yangtools.yang.model.repo.api.SchemaSourceRepresentation;
24 import org.opendaylight.yangtools.yang.model.repo.api.YangIRSchemaSource;
25 import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
26 import org.opendaylight.yangtools.yang.model.repo.api.YinDomSchemaSource;
27 import org.opendaylight.yangtools.yang.model.repo.api.YinTextSchemaSource;
28 import org.opendaylight.yangtools.yang.model.repo.api.YinXmlSchemaSource;
29 import org.opendaylight.yangtools.yang.parser.api.YangParser;
30 import org.opendaylight.yangtools.yang.parser.api.YangParserException;
31 import org.opendaylight.yangtools.yang.parser.api.YangSyntaxErrorException;
32 import org.opendaylight.yangtools.yang.parser.rfc7950.repo.YangStatementStreamSource;
33 import org.opendaylight.yangtools.yang.parser.rfc7950.repo.YinStatementStreamSource;
34 import org.opendaylight.yangtools.yang.parser.rfc7950.repo.YinTextToDomTransformer;
35 import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
36 import org.opendaylight.yangtools.yang.parser.spi.source.StatementStreamSource;
37 import org.opendaylight.yangtools.yang.parser.stmt.reactor.CrossSourceStatementReactor.BuildAction;
38 import org.xml.sax.SAXException;
39
40 final class DefaultYangParser implements YangParser {
41     static final @NonNull Collection<Class<? extends SchemaSourceRepresentation>> REPRESENTATIONS =
42             ImmutableList.of(YangIRSchemaSource.class, YangTextSchemaSource.class, YinDomSchemaSource.class,
43                 YinXmlSchemaSource.class, YinTextSchemaSource.class);
44
45     private final BuildAction buildAction;
46
47     DefaultYangParser(final BuildAction buildAction) {
48         this.buildAction = requireNonNull(buildAction);
49     }
50
51     @Override
52     public @NonNull Collection<Class<? extends SchemaSourceRepresentation>> supportedSourceRepresentations() {
53         return REPRESENTATIONS;
54     }
55
56     @Override
57     public @NonNull YangParser addSource(final SchemaSourceRepresentation source) throws IOException,
58             YangSyntaxErrorException {
59         buildAction.addSource(sourceToStatementStream(source));
60         return this;
61     }
62
63     @Override
64     public @NonNull YangParser addLibSource(final SchemaSourceRepresentation source) throws IOException,
65             YangSyntaxErrorException {
66         buildAction.addLibSource(sourceToStatementStream(source));
67         return this;
68     }
69
70     @Override
71     public @NonNull YangParser setSupportedFeatures(final FeatureSet supportedFeatures) {
72         buildAction.setSupportedFeatures(supportedFeatures);
73         return this;
74     }
75
76     @Override
77     public @NonNull YangParser setModulesWithSupportedDeviations(
78             final SetMultimap<QNameModule, QNameModule> modulesDeviatedByModules) {
79         buildAction.setModulesWithSupportedDeviations(modulesDeviatedByModules);
80         return this;
81     }
82
83     @Override
84     public @NonNull List<DeclaredStatement<?>> buildDeclaredModel() throws YangParserException {
85         try {
86             return buildAction.build().getRootStatements();
87         } catch (ReactorException e) {
88             throw decodeReactorException(e);
89         }
90     }
91
92     @Override
93     public @NonNull EffectiveModelContext buildEffectiveModel() throws YangParserException {
94         try {
95             return buildAction.buildEffective();
96         } catch (ReactorException e) {
97             throw decodeReactorException(e);
98         }
99     }
100
101     static YangParserException decodeReactorException(final ReactorException reported) {
102         // FIXME: map exception in some reasonable manner
103         return new YangParserException("Failed to assemble sources", reported);
104     }
105
106     static StatementStreamSource sourceToStatementStream(final SchemaSourceRepresentation source)
107             throws IOException, YangSyntaxErrorException {
108         requireNonNull(source);
109         if (source instanceof YangIRSchemaSource) {
110             return YangStatementStreamSource.create((YangIRSchemaSource) source);
111         } else if (source instanceof YangTextSchemaSource) {
112             return YangStatementStreamSource.create((YangTextSchemaSource) source);
113         } else if (source instanceof YinDomSchemaSource) {
114             return YinStatementStreamSource.create((YinDomSchemaSource) source);
115         } else if (source instanceof YinTextSchemaSource) {
116             try {
117                 return YinStatementStreamSource.create(YinTextToDomTransformer.transformSource(
118                     (YinTextSchemaSource) source));
119             } catch (SAXException e) {
120                 throw new YangSyntaxErrorException(source.getIdentifier(), 0, 0, "Failed to parse XML text", e);
121             }
122         } else if (source instanceof YinXmlSchemaSource) {
123             try {
124                 return YinStatementStreamSource.create((YinXmlSchemaSource) source);
125             } catch (TransformerException e) {
126                 throw new YangSyntaxErrorException(source.getIdentifier(), 0, 0,
127                     "Failed to assemble in-memory representation", e);
128             }
129         } else {
130             throw new IllegalArgumentException("Unsupported source " + source);
131         }
132     }
133 }