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