BUG-997 Add tests for shared schema context and fix dependency resolution bug
[yangtools.git] / yang / yang-parser-impl / src / main / java / org / opendaylight / yangtools / yang / parser / util / ASTSchemaSource.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.annotations.Beta;
10 import com.google.common.base.Function;
11 import com.google.common.base.Preconditions;
12 import javax.annotation.Nonnull;
13 import org.antlr.v4.runtime.ParserRuleContext;
14 import org.opendaylight.yangtools.yang.model.parser.api.YangSyntaxErrorException;
15 import org.opendaylight.yangtools.yang.model.repo.api.SchemaSourceRepresentation;
16 import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
17 import org.opendaylight.yangtools.yang.parser.impl.util.YangModelDependencyInfo;
18
19 /**
20  * Abstract Syntax Tree representation of a schema source. This representation
21  * is internal to the YANG parser implementation, as it relies on ANTLR types.
22  *
23  * Instances of this representation are used for caching purposes, as they
24  * are a natural intermediate step in YANG text processing pipeline: the text
25  * has been successfully parsed, so we know it is syntactically correct. It also
26  * passes basic semantic validation and we were able to extract dependency
27  * information.
28  */
29 @Beta
30 public final class ASTSchemaSource implements SchemaSourceRepresentation {
31     public static final Function<ASTSchemaSource, SourceIdentifier> GET_IDENTIFIER = new Function<ASTSchemaSource, SourceIdentifier>() {
32         @Override
33         public SourceIdentifier apply(final ASTSchemaSource input) {
34             return input.getIdentifier();
35         }
36     };
37     public static final Function<ASTSchemaSource, YangModelDependencyInfo> GET_DEPINFO = new Function<ASTSchemaSource, YangModelDependencyInfo>() {
38         @Override
39         public YangModelDependencyInfo apply(final ASTSchemaSource input) {
40             return input.getDependencyInformation();
41         }
42     };
43     public static final Function<ASTSchemaSource, ParserRuleContext> GET_AST = new Function<ASTSchemaSource, ParserRuleContext>() {
44         @Override
45         public ParserRuleContext apply(final ASTSchemaSource input) {
46             return input.getAST();
47         }
48     };
49
50     private final YangModelDependencyInfo depInfo;
51     private final ParserRuleContext tree;
52     private final SourceIdentifier id;
53     private final String text;
54
55     private ASTSchemaSource(final @Nonnull SourceIdentifier id, @Nonnull final ParserRuleContext tree, final @Nonnull YangModelDependencyInfo depInfo, final @Nonnull String text) {
56         this.depInfo = Preconditions.checkNotNull(depInfo);
57         this.tree = Preconditions.checkNotNull(tree);
58         this.id = Preconditions.checkNotNull(id);
59         this.text = Preconditions.checkNotNull(text);
60     }
61
62     /**
63      * Create a new instance of AST representation for a abstract syntax tree,
64      * performing minimal semantic analysis to acquire dependency information.
65      *
66      * @param name YANG source name. Used only for error reporting.
67      * @param tree ANTLR abstract syntax tree
68      * @return A new representation instance.
69      * @throws YangSyntaxErrorException if we fail to extract dependency information.
70      */
71     public static ASTSchemaSource create(final @Nonnull String name, final @Nonnull ParserRuleContext tree) throws YangSyntaxErrorException {
72         final YangModelDependencyInfo depInfo = YangModelDependencyInfo.fromAST(name, tree);
73         final SourceIdentifier id = getSourceId(depInfo);
74         return new ASTSchemaSource(id, tree, depInfo, null);
75     }
76
77     private static SourceIdentifier getSourceId(final YangModelDependencyInfo depInfo) {
78         final String name = depInfo.getName();
79         return depInfo.getFormattedRevision() == null
80                 ? new SourceIdentifier(name)
81                 : new SourceIdentifier(name, depInfo.getFormattedRevision());
82     }
83
84     /**
85      * Create a new instance of AST representation for a abstract syntax tree,
86      * performing minimal semantic analysis to acquire dependency information.
87      *
88      * @param name YANG source name. Used only for error reporting.
89      * @param tree ANTLR abstract syntax tree
90      * @return A new representation instance.
91      * @throws YangSyntaxErrorException if we fail to extract dependency information.
92      *
93      * @deprecated Migration only, will be removed as soon as the migration is completed.
94      */
95     @Deprecated
96     public static ASTSchemaSource create(final @Nonnull String name, final @Nonnull ParserRuleContext tree, final String text) throws YangSyntaxErrorException {
97         final YangModelDependencyInfo depInfo = YangModelDependencyInfo.fromAST(name, tree);
98         final SourceIdentifier id = getSourceId(depInfo);
99         return new ASTSchemaSource(id, tree, depInfo, text);
100     }
101
102
103     @Override
104     public SourceIdentifier getIdentifier() {
105         return id;
106     }
107
108     @Override
109     public Class<? extends SchemaSourceRepresentation> getType() {
110         return ASTSchemaSource.class;
111     }
112
113     /**
114      * Return the underlying abstract syntax tree.
115      *
116      * @return Underlying AST.
117      */
118     public @Nonnull ParserRuleContext getAST() {
119         return tree;
120     }
121
122     /**
123      * Return the dependency information as extracted from the AST.
124      *
125      * FIXME: this method should be extracted into a public interface in the
126      *        model.api.repo class, relying solely on model.api types.
127      *
128      * @return Dependency information.
129      */
130     public @Nonnull YangModelDependencyInfo getDependencyInformation() {
131         return depInfo;
132     }
133
134     /**
135      * Return the semantically-equivalent text YANG text source.
136      *
137      * @return YANG text source
138      * @deprecated Used for migration purposes. Users are advised to use the
139      *             schema repository to acquire the representation of their
140      *             choice. Will be removed as soon as the migration is completed.
141      */
142     @Deprecated
143     public @Nonnull String getYangText() {
144         return text;
145     }
146 }