Bug 4640: Change semantic-version to openconfig-version
[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  *
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.util;
9
10 import static org.opendaylight.yangtools.yang.model.api.Module.DEFAULT_OPENCONFIG_VERSION;
11
12 import com.google.common.annotations.Beta;
13 import com.google.common.base.Function;
14 import com.google.common.base.Preconditions;
15 import java.util.Optional;
16 import javax.annotation.Nonnull;
17 import javax.annotation.Nullable;
18 import org.antlr.v4.runtime.ParserRuleContext;
19 import org.opendaylight.yangtools.yang.model.parser.api.YangSyntaxErrorException;
20 import org.opendaylight.yangtools.yang.model.repo.api.RevisionSourceIdentifier;
21 import org.opendaylight.yangtools.yang.model.repo.api.SchemaSourceRepresentation;
22 import org.opendaylight.yangtools.yang.model.repo.api.OpenconfigVerSourceIdentifier;
23 import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
24 import org.opendaylight.yangtools.yang.parser.impl.util.YangModelDependencyInfo;
25
26 /**
27  * Abstract Syntax Tree representation of a schema source. This representation
28  * is internal to the YANG parser implementation, as it relies on ANTLR types.
29  *
30  * Instances of this representation are used for caching purposes, as they
31  * are a natural intermediate step in YANG text processing pipeline: the text
32  * has been successfully parsed, so we know it is syntactically correct. It also
33  * passes basic semantic validation and we were able to extract dependency
34  * information.
35  */
36 @Beta
37 public final class ASTSchemaSource implements SchemaSourceRepresentation {
38     @Deprecated
39     public static final Function<ASTSchemaSource, SourceIdentifier> GET_IDENTIFIER =
40         ASTSchemaSource::getIdentifier;
41     @Deprecated
42     public static final Function<ASTSchemaSource, SourceIdentifier> GET_SEMVER_IDENTIFIER =
43         ASTSchemaSource::getSemVerIdentifier;
44     @Deprecated
45     public static final Function<ASTSchemaSource, YangModelDependencyInfo> GET_DEPINFO =
46         ASTSchemaSource::getDependencyInformation;
47     @Deprecated
48     public static final Function<ASTSchemaSource, ParserRuleContext> GET_AST = ASTSchemaSource::getAST;
49
50     private final YangModelDependencyInfo depInfo;
51     private final OpenconfigVerSourceIdentifier semVerId;
52     private final ParserRuleContext tree;
53     private final SourceIdentifier id;
54     private final String symbolicName;
55
56     private ASTSchemaSource(@Nonnull final SourceIdentifier id, @Nonnull final OpenconfigVerSourceIdentifier semVerId,
57             @Nonnull final ParserRuleContext tree, @Nonnull final YangModelDependencyInfo depInfo,
58             @Nullable final String symbolicName) {
59         this.depInfo = Preconditions.checkNotNull(depInfo);
60         this.tree = Preconditions.checkNotNull(tree);
61         this.id = Preconditions.checkNotNull(id);
62         this.semVerId = Preconditions.checkNotNull(semVerId);
63         this.symbolicName = symbolicName;
64     }
65
66     /**
67      * Create a new instance of AST representation for a abstract syntax tree,
68      * performing minimal semantic analysis to acquire dependency information.
69      *
70      * @param name YANG source name. Used only for error reporting.
71      * @param tree ANTLR abstract syntax tree
72      * @return A new representation instance.
73      * @throws YangSyntaxErrorException if we fail to extract dependency information.
74      */
75     public static ASTSchemaSource create(@Nonnull final String name, @Nonnull final ParserRuleContext tree)
76             throws YangSyntaxErrorException {
77         final YangModelDependencyInfo depInfo = YangModelDependencyInfo.fromAST(name, tree);
78         final SourceIdentifier id = getSourceId(depInfo);
79         final OpenconfigVerSourceIdentifier semVerId = getOpenconfigVerSourceId(depInfo);
80         return new ASTSchemaSource(id, semVerId, tree, depInfo, null);
81     }
82
83     private static SourceIdentifier getSourceId(final YangModelDependencyInfo depInfo) {
84         final String name = depInfo.getName();
85         return depInfo.getFormattedRevision() == null ? RevisionSourceIdentifier.create(name)
86                 : RevisionSourceIdentifier.create(name, depInfo.getFormattedRevision());
87     }
88
89     private static OpenconfigVerSourceIdentifier getOpenconfigVerSourceId(final YangModelDependencyInfo depInfo) {
90         return depInfo.getFormattedRevision() == null
91                 ? OpenconfigVerSourceIdentifier.create(depInfo.getName(),
92                     depInfo.getOpenconfigVersion().or(DEFAULT_OPENCONFIG_VERSION))
93                         : OpenconfigVerSourceIdentifier.create(depInfo.getName(), depInfo.getFormattedRevision(),
94                             depInfo.getOpenconfigVersion().or(DEFAULT_OPENCONFIG_VERSION));
95     }
96
97     /**
98      * Create a new instance of AST representation for a abstract syntax tree,
99      * performing minimal semantic analysis to acquire dependency information.
100      *
101      * @param identifier
102      *            SourceIdentifier of yang schema source.
103      * @param tree
104      *            ANTLR abstract syntax tree
105      * @param text
106      *            YANG text source
107      * @return A new representation instance.
108      * @throws YangSyntaxErrorException
109      *             if we fail to extract dependency information.
110      *
111      * @deprecated Use {@link #create(SourceIdentifier, ParserRuleContext)} instead.
112      */
113     @Deprecated
114     public static ASTSchemaSource create(@Nonnull final SourceIdentifier identifier,
115             @Nonnull final ParserRuleContext tree, final String text) throws YangSyntaxErrorException {
116         return create(identifier, tree);
117     }
118
119     /**
120      * Create a new instance of AST representation for a abstract syntax tree, performing minimal semantic analysis
121      * to acquire dependency information.
122      *
123      * @param identifier
124      *            SourceIdentifier of yang schema source.
125      * @param tree
126      *            ANTLR abstract syntax tree
127      * @return A new representation instance.
128      * @throws YangSyntaxErrorException
129      *             if we fail to extract dependency information.
130      */
131     public static ASTSchemaSource create(@Nonnull final SourceIdentifier identifier,
132             @Nonnull final ParserRuleContext tree) throws YangSyntaxErrorException {
133         return create(identifier, null, tree);
134     }
135
136     /**
137      * Create a new instance of AST representation for a abstract syntax tree, performing minimal semantic analysis
138      * to acquire dependency information.
139      *
140      * @param symbolicName
141      *            Symbolic name
142      * @param identifier
143      *            SourceIdentifier of yang schema source.
144      * @param tree
145      *            ANTLR abstract syntax tree
146      * @return A new representation instance.
147      * @throws YangSyntaxErrorException
148      *             if we fail to extract dependency information.
149      */
150     public static ASTSchemaSource create(@Nonnull final String symbolicName, @Nonnull final SourceIdentifier identifier,
151             @Nonnull final ParserRuleContext tree) throws YangSyntaxErrorException {
152         return create(identifier, symbolicName, tree);
153     }
154
155     private static ASTSchemaSource create(@Nonnull final SourceIdentifier identifier,
156             @Nullable final String symbolicName, @Nonnull final ParserRuleContext tree)
157                     throws YangSyntaxErrorException {
158         final YangModelDependencyInfo depInfo = YangModelDependencyInfo.fromAST(identifier.getName(), tree);
159         final SourceIdentifier id = getSourceId(depInfo);
160
161         final OpenconfigVerSourceIdentifier semVerId;
162         if (identifier instanceof OpenconfigVerSourceIdentifier && !depInfo.getOpenconfigVersion().isPresent()) {
163             semVerId = (OpenconfigVerSourceIdentifier) identifier;
164         } else {
165             semVerId = getOpenconfigVerSourceId(depInfo);
166         }
167
168         return new ASTSchemaSource(id, semVerId, tree, depInfo, symbolicName);
169     }
170
171
172     @Override
173     public SourceIdentifier getIdentifier() {
174         return id;
175     }
176
177     @Override
178     public Optional<String> getSymbolicName() {
179         return Optional.ofNullable(symbolicName);
180     }
181
182     public OpenconfigVerSourceIdentifier getSemVerIdentifier() {
183         return semVerId;
184     }
185
186     @Nonnull
187     @Override
188     public Class<? extends SchemaSourceRepresentation> getType() {
189         return ASTSchemaSource.class;
190     }
191
192     /**
193      * Return the underlying abstract syntax tree.
194      *
195      * @return Underlying AST.
196      */
197     @Nonnull public ParserRuleContext getAST() {
198         return tree;
199     }
200
201     /**
202      * Return the dependency information as extracted from the AST.
203      *
204      * FIXME: this method should be extracted into a public interface in the
205      *        model.api.repo class, relying solely on model.api types.
206      *
207      * @return Dependency information.
208      */
209     @Nonnull public YangModelDependencyInfo getDependencyInformation() {
210         return depInfo;
211     }
212 }