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