BUG-997: Rework URLSchemaContextResolver
[yangtools.git] / yang / yang-parser-impl / src / main / java / org / opendaylight / yangtools / yang / parser / util / TextToASTTransformer.java
1 /*
2  * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
3  * This program and the accompanying materials are made available under the
4  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
5  * and is available at http://www.eclipse.org/legal/epl-v10.html
6  */
7 package org.opendaylight.yangtools.yang.parser.util;
8
9 import com.google.common.base.Function;
10 import com.google.common.base.Preconditions;
11 import com.google.common.util.concurrent.CheckedFuture;
12 import com.google.common.util.concurrent.Futures;
13 import com.google.common.util.concurrent.ListeningExecutorService;
14
15 import java.io.IOException;
16 import java.io.InputStream;
17 import java.util.concurrent.Callable;
18
19 import org.antlr.v4.runtime.tree.ParseTreeWalker;
20 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.YangContext;
21 import org.opendaylight.yangtools.util.concurrent.ExceptionMapper;
22 import org.opendaylight.yangtools.yang.model.parser.api.YangSyntaxErrorException;
23 import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
24 import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceTransformationException;
25 import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceTransformer;
26 import org.opendaylight.yangtools.yang.parser.impl.YangModelBasicValidationListener;
27 import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
30
31 /**
32  * A {@link SchemaSourceTransformer} which handles translation of models from
33  * {@link YangTextSchemaSource} representation into {@link ASTSchemaSource}.
34  *
35  * While this class is currently used explicitly, its long-term purpose is to
36  * be registered with a {@link org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceRegistry}
37  * and be invoked on demand when the processing pipeline requests the
38  * ASTSchemaSource representation.
39  */
40 public final class TextToASTTransformer implements SchemaSourceTransformer<YangTextSchemaSource, ASTSchemaSource> {
41     private static final Logger LOG = LoggerFactory.getLogger(TextToASTTransformer.class);
42     private static final Function<Exception, SchemaSourceTransformationException> MAPPER = new ExceptionMapper<SchemaSourceTransformationException>("Source transformation", SchemaSourceTransformationException.class) {
43         @Override
44         protected SchemaSourceTransformationException newWithCause(final String message, final Throwable cause) {
45             return new SchemaSourceTransformationException(message, cause);
46         }
47     };
48
49     private final ListeningExecutorService executor;
50
51     private TextToASTTransformer(final ListeningExecutorService executor) {
52         this.executor = Preconditions.checkNotNull(executor);
53     }
54
55     public static final TextToASTTransformer create(final ListeningExecutorService executor) {
56         return new TextToASTTransformer(executor);
57     }
58
59     @Override
60     public Class<YangTextSchemaSource> getInputRepresentation() {
61         return YangTextSchemaSource.class;
62     }
63
64     @Override
65     public Class<ASTSchemaSource> getOutputRepresentation() {
66         return ASTSchemaSource.class;
67     }
68
69     @Override
70     public CheckedFuture<ASTSchemaSource, SchemaSourceTransformationException> transformSchemaSource(final YangTextSchemaSource source) {
71         return Futures.makeChecked(executor.submit(new Callable<ASTSchemaSource>() {
72             @Override
73             public ASTSchemaSource call() throws IOException, YangSyntaxErrorException {
74                 try (InputStream is = source.openStream()) {
75                     final YangContext ctx = YangParserImpl.parseYangSource(is);
76                     LOG.debug("Model {} parsed successfully", source);
77
78                     final ParseTreeWalker walker = new ParseTreeWalker();
79                     final YangModelBasicValidationListener validator = new YangModelBasicValidationListener();
80                     walker.walk(validator, ctx);
81                     LOG.debug("Model {} validated successfully", source);
82
83                     return ASTSchemaSource.create(source.getIdentifier().getName(), ctx);
84                 }
85             }
86         }), MAPPER);
87     }
88
89     @Override
90     public int getCost() {
91         // We perform a direct translation, so the cost is 1.
92         return 1;
93     }
94 }