BUG-7052: introduce YangStatementStreamSource 55/52055/10
authorRobert Varga <robert.varga@pantheon.tech>
Sun, 19 Feb 2017 23:30:35 +0000 (00:30 +0100)
committerRobert Varga <robert.varga@pantheon.tech>
Thu, 23 Feb 2017 08:59:53 +0000 (09:59 +0100)
This untangles the parser implementation a bit, adding a more
modern StatementStreamSource.

Change-Id: Ic5fb23f088273e1a0993663bab237b6432924b47
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/util/YangModelDependencyInfo.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/rfc6020/repo/YangStatementStreamSource.java [new file with mode: 0644]
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/CrossSourceStatementReactor.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/YangStatementSourceImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/util/TextToASTTransformer.java

index 8ff67703179cb3a16b3961e93c595cd96485b998..0b25b504011551b6d4c0da2f1d18b557ec684c09 100644 (file)
@@ -190,21 +190,14 @@ public abstract class YangModelDependencyInfo {
     }
 
     private static YangModelDependencyInfo parseAST(final StatementContext rootStatement) {
-        if (rootStatement
-                .keyword()
-                .getText()
-                .equals(YangStmtMapping.MODULE.getStatementName().getLocalName())) {
+        final String keyWordText = rootStatement.keyword().getText();
+        if (YangStmtMapping.MODULE.getStatementName().getLocalName().equals(keyWordText)) {
             return parseModuleContext(rootStatement);
-        } else if (rootStatement
-                .keyword()
-                .getText()
-                .equals(YangStmtMapping.SUBMODULE.getStatementName()
-                        .getLocalName())) {
+        }
+        if (YangStmtMapping.SUBMODULE.getStatementName().getLocalName().equals(keyWordText)) {
             return parseSubmoduleContext(rootStatement);
         }
-
-        throw new IllegalArgumentException(
-                "Root of parsed AST must be either module or submodule");
+        throw new IllegalArgumentException("Root of parsed AST must be either module or submodule");
     }
 
     /**
@@ -220,10 +213,8 @@ public abstract class YangModelDependencyInfo {
      * @throws IllegalArgumentException
      *             If input stream is not valid YANG stream
      */
-    public static YangModelDependencyInfo fromInputStream(
-            final InputStream yangStream) {
-        final StatementContext yangAST = new YangStatementSourceImpl(yangStream)
-                .getYangAST();
+    public static YangModelDependencyInfo fromInputStream(final InputStream yangStream) {
+        final StatementContext yangAST = new YangStatementSourceImpl(yangStream).getYangAST();
         return parseAST(yangAST);
     }
 
diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/rfc6020/repo/YangStatementStreamSource.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/rfc6020/repo/YangStatementStreamSource.java
new file mode 100644 (file)
index 0000000..57824cf
--- /dev/null
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2017 Pantheon Technologies, s.r.o. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.parser.rfc6020.repo;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
+import java.io.IOException;
+import java.io.InputStream;
+import org.antlr.v4.runtime.ANTLRInputStream;
+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.Identifiable;
+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.impl.YangStatementParserListenerImpl;
+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.StatementStreamSource;
+import org.opendaylight.yangtools.yang.parser.spi.source.StatementWriter;
+
+/**
+ * This class represents implementation of StatementStreamSource in order to emit YANG statements using supplied
+ * StatementWriter.
+ *
+ * @author Robert Varga
+ */
+@Beta
+public final class YangStatementStreamSource implements Identifiable<SourceIdentifier>, 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 YangStatementParserListenerImpl yangStatementModelParser;
+    private final SourceIdentifier identifier;
+    private final StatementContext context;
+
+    private YangStatementStreamSource(final SourceIdentifier identifier, final YangStatementParserListenerImpl parser,
+            final StatementContext context) {
+        this.identifier = Preconditions.checkNotNull(identifier);
+        this.yangStatementModelParser = Preconditions.checkNotNull(parser);
+        this.context = Preconditions.checkNotNull(context);
+    }
+
+    public static YangStatementStreamSource create(final YangTextSchemaSource source) throws IOException,
+            YangSyntaxErrorException {
+        final StatementContext context;
+        try (final InputStream stream = source.openStream()) {
+            context = parseYangSource(stream);
+        }
+
+        final String sourceName = source.getSymbolicName().orElse(null);
+        final YangStatementParserListenerImpl parser = new YangStatementParserListenerImpl(sourceName);
+        return new YangStatementStreamSource(source.getIdentifier(), parser, context);
+    }
+
+    @Override
+    public void writePreLinkage(final StatementWriter writer, final QNameToStatementDefinition stmtDef) {
+        yangStatementModelParser.setAttributes(writer, stmtDef);
+        ParseTreeWalker.DEFAULT.walk(yangStatementModelParser, context);
+    }
+
+    @Override
+    public void writeLinkage(final StatementWriter writer, final QNameToStatementDefinition stmtDef,
+            final PrefixToModule preLinkagePrefixes) {
+        yangStatementModelParser.setAttributes(writer, stmtDef, preLinkagePrefixes);
+        ParseTreeWalker.DEFAULT.walk(yangStatementModelParser, context);
+    }
+
+    @Override
+    public void writeLinkageAndStatementDefinitions(final StatementWriter writer,
+            final QNameToStatementDefinition stmtDef, final PrefixToModule prefixes) {
+        yangStatementModelParser.setAttributes(writer, stmtDef, prefixes);
+        ParseTreeWalker.DEFAULT.walk(yangStatementModelParser, context);
+    }
+
+    @Override
+    public void writeFull(final StatementWriter writer, final QNameToStatementDefinition stmtDef,
+            final PrefixToModule prefixes) {
+        yangStatementModelParser.setAttributes(writer, stmtDef, prefixes);
+        ParseTreeWalker.DEFAULT.walk(yangStatementModelParser, context);
+    }
+
+    @Override
+    public SourceIdentifier getIdentifier() {
+        return identifier;
+    }
+
+    public ParserRuleContext getYangAST() {
+        return context;
+    }
+
+    /**
+     * @deprecated Provided for migration purposes only. Do not use.
+     */
+    @Deprecated
+    public static StatementContext parseYangSource(final InputStream stream) throws IOException,
+            YangSyntaxErrorException {
+        final YangStatementLexer lexer = new YangStatementLexer(new ANTLRInputStream(stream));
+        final CommonTokenStream tokens = new CommonTokenStream(lexer);
+        final YangStatementParser parser = new YangStatementParser(tokens);
+        //disconnect from console error output
+        parser.removeErrorListeners();
+
+        final YangErrorListener errorListener = new YangErrorListener();
+        parser.addErrorListener(errorListener);
+
+        final StatementContext result = parser.statement();
+        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;
+    }
+}
index ac45c024168658c7ae7d29e0949eaef1b6826e29..56efa9c1d48e9dddfb0ba6c70d9017486f419cb8 100644 (file)
@@ -21,6 +21,7 @@ import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.opendaylight.yangtools.yang.model.parser.api.YangSyntaxErrorException;
 import org.opendaylight.yangtools.yang.model.repo.api.StatementParserMode;
 import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
+import org.opendaylight.yangtools.yang.parser.rfc6020.repo.YangStatementStreamSource;
 import org.opendaylight.yangtools.yang.parser.spi.meta.ModelProcessingPhase;
 import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StatementSupportBundle;
@@ -164,7 +165,7 @@ public class CrossSourceStatementReactor {
             for (final ByteSource source : yangByteSources) {
                 if (source instanceof YangTextSchemaSource) {
                     try {
-                        addSource(YangStatementSourceImpl.create((YangTextSchemaSource) source));
+                        addSource(YangStatementStreamSource.create((YangTextSchemaSource) source));
                     } catch (YangSyntaxErrorException e) {
                         throw new IOException("Source " + source + " failed to parse", e);
                     }
index fbaa1f83a6e1a96abd5522995da54690c4ab1932..3b561918bfccdeb3675035beb7ee8e00a6a73676 100644 (file)
@@ -8,28 +8,17 @@
 
 package org.opendaylight.yangtools.yang.parser.stmt.rfc6020;
 
-import com.google.common.base.Preconditions;
 import com.google.common.base.Throwables;
-import com.google.common.collect.ImmutableList;
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.URISyntaxException;
-import org.antlr.v4.runtime.ANTLRInputStream;
-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.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.impl.YangStatementParserListenerImpl;
-import org.opendaylight.yangtools.yang.parser.rfc6020.repo.YangErrorListener;
+import org.opendaylight.yangtools.yang.parser.rfc6020.repo.YangStatementStreamSource;
 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.StatementStreamSource;
@@ -38,48 +27,22 @@ import org.opendaylight.yangtools.yang.parser.util.NamedFileInputStream;
 import org.opendaylight.yangtools.yang.parser.util.NamedInputStream;
 
 /**
- * This class represents implementation of StatementStreamSource
- * in order to emit YANG statements using supplied StatementWriter.
+ * This class represents implementation of StatementStreamSource in order to emit YANG statements using supplied
+ * StatementWriter.
+ *
+ * @deprecated Use {@link YangStatementStreamSource} instead.
  */
+@Deprecated
 public final class YangStatementSourceImpl 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 YangStatementParserListenerImpl yangStatementModelParser;
     private final StatementContext statementContext;
     private final String sourceName;
 
-    private YangStatementSourceImpl(final YangStatementParserListenerImpl parser, final StatementContext context,
-            final String sourceName) {
-        this.yangStatementModelParser = Preconditions.checkNotNull(parser);
-        this.statementContext = Preconditions.checkNotNull(context);
-        this.sourceName = sourceName;
-    }
-
     public YangStatementSourceImpl(final String fileName, final boolean isAbsolute) {
         try {
             final NamedFileInputStream is = loadFile(fileName, isAbsolute);
             sourceName = is.toString();
-            statementContext = parseYangSource(is);
+            statementContext = YangStatementStreamSource.parseYangSource(is);
             yangStatementModelParser = new YangStatementParserListenerImpl(sourceName);
         } catch (IOException | URISyntaxException | YangSyntaxErrorException e) {
             throw Throwables.propagate(e);
@@ -89,7 +52,7 @@ public final class YangStatementSourceImpl implements StatementStreamSource {
     public YangStatementSourceImpl(final InputStream inputStream) {
         try {
             sourceName = inputStream instanceof NamedInputStream ? inputStream.toString() : null;
-            statementContext = parseYangSource(inputStream);
+            statementContext = YangStatementStreamSource.parseYangSource(inputStream);
             yangStatementModelParser = new YangStatementParserListenerImpl(sourceName);
         } catch (IOException | YangSyntaxErrorException e) {
             throw Throwables.propagate(e);
@@ -102,19 +65,6 @@ public final class YangStatementSourceImpl implements StatementStreamSource {
         yangStatementModelParser = new YangStatementParserListenerImpl(sourceName);
     }
 
-    public static YangStatementSourceImpl create(final YangTextSchemaSource source) throws IOException,
-            YangSyntaxErrorException {
-        final StatementContext context;
-        try (final InputStream stream = source.openStream()) {
-            context = parseYangSource(source.openStream());
-        }
-
-        final String sourceName = source.getSymbolicName().orElse(null);
-        final YangStatementParserListenerImpl parser = new YangStatementParserListenerImpl(sourceName);
-
-        return new YangStatementSourceImpl(parser, context, sourceName);
-    }
-
     @Override
     public void writePreLinkage(final StatementWriter writer, final QNameToStatementDefinition stmtDef) {
         yangStatementModelParser.setAttributes(writer, stmtDef);
@@ -149,28 +99,6 @@ public final class YangStatementSourceImpl implements StatementStreamSource {
                 : new NamedFileInputStream(new File(getClass().getResource(fileName).toURI()), fileName);
     }
 
-    private static StatementContext parseYangSource(final InputStream stream) throws IOException,
-            YangSyntaxErrorException {
-        final YangStatementLexer lexer = new YangStatementLexer(new ANTLRInputStream(stream));
-        final CommonTokenStream tokens = new CommonTokenStream(lexer);
-        final YangStatementParser parser = new YangStatementParser(tokens);
-        //disconnect from console error output
-        parser.removeErrorListeners();
-
-        final YangErrorListener errorListener = new YangErrorListener();
-        parser.addErrorListener(errorListener);
-
-        final StatementContext result = parser.statement();
-        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;
-    }
-
     public StatementContext getYangAST() {
         return statementContext;
     }
index 216d60ba93899c7a973934139d88d6e675f29e29..b9b48ac2dade1feacbd0f04006c59795d71cc37b 100644 (file)
@@ -21,7 +21,7 @@ import org.opendaylight.yangtools.yang.model.repo.api.SchemaSourceException;
 import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
 import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceRegistry;
 import org.opendaylight.yangtools.yang.model.repo.util.SchemaSourceTransformer;
-import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.YangStatementSourceImpl;
+import org.opendaylight.yangtools.yang.parser.rfc6020.repo.YangStatementStreamSource;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -40,7 +40,7 @@ public final class TextToASTTransformer extends SchemaSourceTransformer<YangText
         @Override
         public CheckedFuture<ASTSchemaSource, SchemaSourceException> apply(@Nonnull final YangTextSchemaSource input)
                 throws IOException, YangSyntaxErrorException {
-            final YangStatementSourceImpl src = YangStatementSourceImpl.create(input);
+            final YangStatementStreamSource src = YangStatementStreamSource.create(input);
 
             final ParserRuleContext ctx = src.getYangAST();
             LOG.debug("Model {} parsed successfully", input);