*/
package org.opendaylight.yangtools.yang.parser.rfc7950.repo;
-import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Verify.verifyNotNull;
import static java.util.Objects.requireNonNull;
import com.google.common.annotations.Beta;
-import com.google.common.collect.ImmutableList;
import java.io.IOException;
import java.io.InputStream;
import org.antlr.v4.runtime.CharStreams;
import org.antlr.v4.runtime.CommonTokenStream;
-import org.antlr.v4.runtime.ParserRuleContext;
-import org.antlr.v4.runtime.tree.ErrorNode;
-import org.antlr.v4.runtime.tree.ParseTreeListener;
-import org.antlr.v4.runtime.tree.ParseTreeWalker;
-import org.antlr.v4.runtime.tree.TerminalNode;
-import org.opendaylight.yangtools.antlrv4.code.gen.YangStatementLexer;
-import org.opendaylight.yangtools.antlrv4.code.gen.YangStatementParser;
-import org.opendaylight.yangtools.antlrv4.code.gen.YangStatementParser.StatementContext;
import org.opendaylight.yangtools.concepts.AbstractIdentifiable;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.common.QNameModule;
import org.opendaylight.yangtools.yang.model.parser.api.YangSyntaxErrorException;
import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
+import org.opendaylight.yangtools.yang.parser.antlr.YangStatementLexer;
+import org.opendaylight.yangtools.yang.parser.antlr.YangStatementParser;
+import org.opendaylight.yangtools.yang.parser.antlr.YangStatementParser.FileContext;
+import org.opendaylight.yangtools.yang.parser.antlr.YangStatementParser.StatementContext;
+import org.opendaylight.yangtools.yang.parser.rfc7950.antlr.CompactYangStatementLexer;
+import org.opendaylight.yangtools.yang.parser.rfc7950.ir.AntlrSupport;
+import org.opendaylight.yangtools.yang.parser.rfc7950.ir.IRKeyword;
+import org.opendaylight.yangtools.yang.parser.rfc7950.ir.IRSchemaSource;
+import org.opendaylight.yangtools.yang.parser.rfc7950.ir.IRStatement;
import org.opendaylight.yangtools.yang.parser.spi.source.PrefixToModule;
import org.opendaylight.yangtools.yang.parser.spi.source.QNameToStatementDefinition;
import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
@Beta
public final class YangStatementStreamSource extends AbstractIdentifiable<SourceIdentifier>
implements StatementStreamSource {
- private static final ParseTreeListener MAKE_IMMUTABLE_LISTENER = new ParseTreeListener() {
- @Override
- public void enterEveryRule(final ParserRuleContext ctx) {
- // No-op
- }
-
- @Override
- public void exitEveryRule(final ParserRuleContext ctx) {
- ctx.children = ctx.children == null ? ImmutableList.of() : ImmutableList.copyOf(ctx.children);
- }
-
- @Override
- public void visitTerminal(final TerminalNode node) {
- // No-op
- }
-
- @Override
- public void visitErrorNode(final ErrorNode node) {
- // No-op
- }
- };
-
- private final StatementContext context;
+ private final IRStatement rootStatement;
private final String sourceName;
- private YangStatementStreamSource(final SourceIdentifier identifier, final StatementContext context,
+ private YangStatementStreamSource(final SourceIdentifier identifier, final IRStatement rootStatement,
final String sourceName) {
super(identifier);
- this.context = requireNonNull(context);
+ this.rootStatement = requireNonNull(rootStatement);
this.sourceName = sourceName;
}
*/
public static YangStatementStreamSource create(final YangTextSchemaSource source) throws IOException,
YangSyntaxErrorException {
- final StatementContext context;
- try (InputStream stream = source.openStream()) {
- context = parseYangSource(source.getIdentifier(), stream);
- }
-
- return new YangStatementStreamSource(source.getIdentifier(), context, source.getSymbolicName().orElse(null));
+ return new YangStatementStreamSource(source.getIdentifier(),
+ AntlrSupport.createStatement(parseYangSource(source)), source.getSymbolicName().orElse(null));
}
/**
- * Create a {@link YangStatementStreamSource} for a {@link ASTSchemaSource}.
+ * Create a {@link YangStatementStreamSource} for a {@link IRSchemaSource}.
*
* @param source YangTextSchemaSource, must not be null
* @return A new {@link YangStatementStreamSource}
+ * @throws NullPointerException if {@code source} is null
*/
- public static YangStatementStreamSource create(final ASTSchemaSource source) {
- final ParserRuleContext ast = source.getAST();
- checkArgument(ast instanceof StatementContext,
- "Unsupported context class %s for source %s", ast.getClass(), source.getIdentifier());
- return create(source.getIdentifier(), (StatementContext) ast, source.getSymbolicName().orElse(null));
+ public static YangStatementStreamSource create(final IRSchemaSource source) {
+ return create(source.getIdentifier(), source.getRootStatement(), source.getSymbolicName().orElse(null));
}
- public static YangStatementStreamSource create(final SourceIdentifier identifier, final StatementContext context,
- final String symbolicName) {
- return new YangStatementStreamSource(identifier, context, symbolicName);
+ public static YangStatementStreamSource create(final SourceIdentifier identifier, final IRStatement rootStatement,
+ final String symbolicName) {
+ return new YangStatementStreamSource(identifier, rootStatement, symbolicName);
}
@Override
public void writePreLinkage(final StatementWriter writer, final QNameToStatementDefinition stmtDef) {
- new StatementContextVisitor(sourceName, writer, stmtDef, null, YangVersion.VERSION_1).visit(context);
+ new StatementContextVisitor(sourceName, writer, stmtDef, null, YangVersion.VERSION_1).visit(rootStatement);
}
@Override
StatementDefinition resolveStatement(final QNameModule module, final String localName) {
return stmtDef.getByNamespaceAndLocalName(module.getNamespace(), localName);
}
- }.visit(context);
+ }.visit(rootStatement);
}
@Override
public void writeLinkageAndStatementDefinitions(final StatementWriter writer,
final QNameToStatementDefinition stmtDef, final PrefixToModule prefixes, final YangVersion yangVersion) {
- new StatementContextVisitor(sourceName, writer, stmtDef, prefixes, yangVersion).visit(context);
+ new StatementContextVisitor(sourceName, writer, stmtDef, prefixes, yangVersion).visit(rootStatement);
}
@Override
final PrefixToModule prefixes, final YangVersion yangVersion) {
new StatementContextVisitor(sourceName, writer, stmtDef, prefixes, yangVersion) {
@Override
- QName getValidStatementDefinition(final String keywordText, final StatementSourceReference ref) {
- return SourceException.throwIfNull(super.getValidStatementDefinition(keywordText, ref), ref,
- "%s is not a YANG statement or use of extension.", keywordText);
+ QName getValidStatementDefinition(final IRKeyword keyword, final StatementSourceReference ref) {
+ final QName ret = super.getValidStatementDefinition(keyword, ref);
+ if (ret == null) {
+ throw new SourceException(ref, "%s is not a YANG statement or use of extension.",
+ keyword.asStringDeclaration());
+ }
+ return ret;
}
- }.visit(context);
+ }.visit(rootStatement);
}
- public ParserRuleContext getYangAST() {
- return context;
+ IRStatement rootStatement() {
+ return rootStatement;
+ }
+
+ static StatementContext parseYangSource(final YangTextSchemaSource source)
+ throws IOException, YangSyntaxErrorException {
+ try (InputStream stream = source.openStream()) {
+ return parseYangSource(source.getIdentifier(), stream);
+ }
}
private static StatementContext parseYangSource(final SourceIdentifier source, final InputStream stream)
throws IOException, YangSyntaxErrorException {
- final YangStatementLexer lexer = new YangStatementLexer(CharStreams.fromStream(stream));
+ final YangStatementLexer lexer = new CompactYangStatementLexer(CharStreams.fromStream(stream));
final YangStatementParser parser = new YangStatementParser(new CommonTokenStream(lexer));
// disconnect from console error output
lexer.removeErrorListeners();
lexer.addErrorListener(errorListener);
parser.addErrorListener(errorListener);
- final StatementContext result = parser.statement();
+ final FileContext result = parser.file();
errorListener.validate();
-
- // Walk the resulting tree and replace each children with an immutable list, lowering memory requirements
- // and making sure the resulting tree will not get accidentally modified. An alternative would be to use
- // org.antlr.v4.runtime.Parser.TrimToSizeListener, but that does not make the tree immutable.
- ParseTreeWalker.DEFAULT.walk(MAKE_IMMUTABLE_LISTENER, result);
-
- return result;
+ return verifyNotNull(result.statement());
}
}