2 * Copyright (c) 2021 PANTHEON.tech, s.r.o. and others. All rights reserved.
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
8 package org.opendaylight.yangtools.yang.parser.impl;
10 import static java.util.Objects.requireNonNull;
12 import com.google.common.collect.ImmutableSet;
13 import com.google.common.collect.SetMultimap;
14 import java.io.IOException;
15 import java.util.List;
16 import javax.xml.transform.TransformerException;
17 import org.eclipse.jdt.annotation.NonNull;
18 import org.opendaylight.yangtools.yang.common.QNameModule;
19 import org.opendaylight.yangtools.yang.ir.YangIRSchemaSource;
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.source.SourceRepresentation;
23 import org.opendaylight.yangtools.yang.model.api.stmt.FeatureSet;
24 import org.opendaylight.yangtools.yang.model.spi.source.YangTextSource;
25 import org.opendaylight.yangtools.yang.model.spi.source.YinDomSource;
26 import org.opendaylight.yangtools.yang.model.spi.source.YinTextSource;
27 import org.opendaylight.yangtools.yang.model.spi.source.YinXmlSource;
28 import org.opendaylight.yangtools.yang.parser.api.YangParser;
29 import org.opendaylight.yangtools.yang.parser.api.YangParserException;
30 import org.opendaylight.yangtools.yang.parser.api.YangSyntaxErrorException;
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;
39 final class DefaultYangParser implements YangParser {
40 static final @NonNull ImmutableSet<Class<? extends SourceRepresentation>> REPRESENTATIONS = ImmutableSet.of(
41 // In order of preference
42 YangIRSchemaSource.class,
48 private final BuildAction buildAction;
50 DefaultYangParser(final BuildAction buildAction) {
51 this.buildAction = requireNonNull(buildAction);
55 public ImmutableSet<Class<? extends SourceRepresentation>> supportedSourceRepresentations() {
56 return REPRESENTATIONS;
60 public YangParser addSource(final SourceRepresentation source) throws IOException, YangSyntaxErrorException {
61 buildAction.addSource(sourceToStatementStream(source));
66 public YangParser addLibSource(final SourceRepresentation source) throws IOException, YangSyntaxErrorException {
67 buildAction.addLibSource(sourceToStatementStream(source));
72 public YangParser setSupportedFeatures(final FeatureSet supportedFeatures) {
73 buildAction.setSupportedFeatures(supportedFeatures);
78 public YangParser setModulesWithSupportedDeviations(
79 final SetMultimap<QNameModule, QNameModule> modulesDeviatedByModules) {
80 buildAction.setModulesWithSupportedDeviations(modulesDeviatedByModules);
85 public List<DeclaredStatement<?>> buildDeclaredModel() throws YangParserException {
87 return buildAction.build().getRootStatements();
88 } catch (ReactorException e) {
89 throw decodeReactorException(e);
94 public EffectiveModelContext buildEffectiveModel() throws YangParserException {
96 return buildAction.buildEffective();
97 } catch (ReactorException e) {
98 throw decodeReactorException(e);
102 static YangParserException decodeReactorException(final ReactorException reported) {
103 // FIXME: map exception in some reasonable manner
104 return new YangParserException("Failed to assemble sources", reported);
107 static StatementStreamSource sourceToStatementStream(final SourceRepresentation source)
108 throws IOException, YangSyntaxErrorException {
109 requireNonNull(source);
110 if (source instanceof YangIRSchemaSource irSource) {
111 return YangStatementStreamSource.create(irSource);
112 } else if (source instanceof YangTextSource yangSource) {
113 return YangStatementStreamSource.create(yangSource);
114 } else if (source instanceof YinDomSource yinDom) {
115 return YinStatementStreamSource.create(yinDom);
116 } else if (source instanceof YinTextSource yinText) {
118 return YinStatementStreamSource.create(YinTextToDomTransformer.transformSource(yinText));
119 } catch (SAXException e) {
120 throw new YangSyntaxErrorException(source.sourceId(), 0, 0, "Failed to parse XML text", e);
122 } else if (source instanceof YinXmlSource yinXml) {
124 return YinStatementStreamSource.create(yinXml);
125 } catch (TransformerException e) {
126 throw new YangSyntaxErrorException(source.sourceId(), 0, 0,
127 "Failed to assemble in-memory representation", e);
130 throw new IllegalArgumentException("Unsupported source " + source);