2 * Copyright (c) 2014 Cisco Systems, Inc. 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.util;
10 import static org.opendaylight.yangtools.yang.model.api.Module.DEFAULT_SEMANTIC_VERSION;
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.SemVerSourceIdentifier;
23 import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
24 import org.opendaylight.yangtools.yang.parser.impl.util.YangModelDependencyInfo;
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.
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
37 public final class ASTSchemaSource implements SchemaSourceRepresentation {
39 public static final Function<ASTSchemaSource, SourceIdentifier> GET_IDENTIFIER =
40 ASTSchemaSource::getIdentifier;
42 public static final Function<ASTSchemaSource, SourceIdentifier> GET_SEMVER_IDENTIFIER =
43 ASTSchemaSource::getSemVerIdentifier;
45 public static final Function<ASTSchemaSource, YangModelDependencyInfo> GET_DEPINFO =
46 ASTSchemaSource::getDependencyInformation;
48 public static final Function<ASTSchemaSource, ParserRuleContext> GET_AST = ASTSchemaSource::getAST;
50 private final YangModelDependencyInfo depInfo;
51 private final SemVerSourceIdentifier semVerId;
52 private final ParserRuleContext tree;
53 private final SourceIdentifier id;
54 private final String symbolicName;
56 private ASTSchemaSource(@Nonnull final SourceIdentifier id, @Nonnull final SemVerSourceIdentifier 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;
67 * Create a new instance of AST representation for a abstract syntax tree,
68 * performing minimal semantic analysis to acquire dependency information.
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.
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 SemVerSourceIdentifier semVerId = getSemVerSourceId(depInfo);
80 return new ASTSchemaSource(id, semVerId, tree, depInfo, null);
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());
89 private static SemVerSourceIdentifier getSemVerSourceId(final YangModelDependencyInfo depInfo) {
90 return depInfo.getFormattedRevision() == null
91 ? SemVerSourceIdentifier.create(depInfo.getName(),
92 depInfo.getSemanticVersion().or(DEFAULT_SEMANTIC_VERSION))
93 : SemVerSourceIdentifier.create(depInfo.getName(), depInfo.getFormattedRevision(),
94 depInfo.getSemanticVersion().or(DEFAULT_SEMANTIC_VERSION));
98 * Create a new instance of AST representation for a abstract syntax tree,
99 * performing minimal semantic analysis to acquire dependency information.
102 * SourceIdentifier of yang schema source.
104 * ANTLR abstract syntax tree
107 * @return A new representation instance.
108 * @throws YangSyntaxErrorException
109 * if we fail to extract dependency information.
111 * @deprecated Use {@link #create(SourceIdentifier, ParserRuleContext)} instead.
114 public static ASTSchemaSource create(@Nonnull final SourceIdentifier identifier,
115 @Nonnull final ParserRuleContext tree, final String text) throws YangSyntaxErrorException {
116 return create(identifier, tree);
120 * Create a new instance of AST representation for a abstract syntax tree, performing minimal semantic analysis
121 * to acquire dependency information.
124 * SourceIdentifier of yang schema source.
126 * ANTLR abstract syntax tree
127 * @return A new representation instance.
128 * @throws YangSyntaxErrorException
129 * if we fail to extract dependency information.
131 public static ASTSchemaSource create(@Nonnull final SourceIdentifier identifier,
132 @Nonnull final ParserRuleContext tree) throws YangSyntaxErrorException {
133 return create(identifier, null, tree);
137 * Create a new instance of AST representation for a abstract syntax tree, performing minimal semantic analysis
138 * to acquire dependency information.
140 * @param symbolicName
143 * SourceIdentifier of yang schema source.
145 * ANTLR abstract syntax tree
146 * @return A new representation instance.
147 * @throws YangSyntaxErrorException
148 * if we fail to extract dependency information.
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);
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);
161 final SemVerSourceIdentifier semVerId;
162 if (identifier instanceof SemVerSourceIdentifier && !depInfo.getSemanticVersion().isPresent()) {
163 semVerId = (SemVerSourceIdentifier) identifier;
165 semVerId = getSemVerSourceId(depInfo);
168 return new ASTSchemaSource(id, semVerId, tree, depInfo, symbolicName);
173 public SourceIdentifier getIdentifier() {
178 public Optional<String> getSymbolicName() {
179 return Optional.ofNullable(symbolicName);
182 public SemVerSourceIdentifier getSemVerIdentifier() {
188 public Class<? extends SchemaSourceRepresentation> getType() {
189 return ASTSchemaSource.class;
193 * Return the underlying abstract syntax tree.
195 * @return Underlying AST.
197 @Nonnull public ParserRuleContext getAST() {
202 * Return the dependency information as extracted from the AST.
204 * FIXME: this method should be extracted into a public interface in the
205 * model.api.repo class, relying solely on model.api types.
207 * @return Dependency information.
209 @Nonnull public YangModelDependencyInfo getDependencyInformation() {