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