BUG-865: deprecate pre-Beryllium parser elements
[yangtools.git] / yang / yang-parser-impl / src / main / java / org / opendaylight / yangtools / yang / parser / impl / YangParserListenerImpl.java
index 39dfbc9222bd7b3a27cc753de40fcc75c32dbeec..ec5e1f1820aa1bf4b5d72249da782f2cf5ee322b 100644 (file)
@@ -21,7 +21,6 @@ import static org.opendaylight.yangtools.yang.parser.impl.ParserListenerUtils.pa
 import static org.opendaylight.yangtools.yang.parser.impl.ParserListenerUtils.parseUserOrdered;
 import static org.opendaylight.yangtools.yang.parser.impl.ParserListenerUtils.parseYinValue;
 import static org.opendaylight.yangtools.yang.parser.impl.ParserListenerUtils.stringFromNode;
-
 import com.google.common.base.Splitter;
 import com.google.common.base.Strings;
 import com.google.common.collect.Iterables;
@@ -34,8 +33,8 @@ import java.util.Date;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.NavigableMap;
 import java.util.Set;
-import java.util.TreeMap;
 import org.antlr.v4.runtime.tree.ParseTree;
 import org.antlr.v4.runtime.tree.ParseTreeWalker;
 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser;
@@ -103,16 +102,26 @@ import org.opendaylight.yangtools.yang.parser.util.YangParseException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-
+/**
+ * @deprecated Pre-Beryllium implementation, scheduled for removal.
+ */
+@Deprecated
 public final class YangParserListenerImpl extends YangParserBaseListener {
     private static final Logger LOG = LoggerFactory.getLogger(YangParserListenerImpl.class);
     private static final Splitter SLASH_SPLITTER = Splitter.on('/').omitEmptyStrings();
     private static final Splitter COLON_SPLITTER = Splitter.on(':');
     private static final String AUGMENT_STR = "augment";
 
-    private final DateFormat SIMPLE_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
+    private static final String IMPORT_STR = "import";
+    private static final String UNION_STR = "union";
+    private static final String UNKNOWN_NODE_STR = "unknown-node";
+
+    /**
+     * Date Format is not thread-safe so we cannot make constant from it.
+     */
+    private final DateFormat revisionFormat = new SimpleDateFormat("yyyy-MM-dd");
     private final SchemaPathStack stack = new SchemaPathStack();
-    private final Map<String, TreeMap<Date, URI>> namespaceContext;
+    private final Map<String, NavigableMap<Date, URI>> namespaceContext;
     private final String sourcePath;
     private QName moduleQName = QName.create(null, new Date(0L), "dummy");
     private ModuleBuilder moduleBuilder;
@@ -120,7 +129,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     private int augmentOrder;
     private String yangModelPrefix;
 
-    public YangParserListenerImpl(final Map<String, TreeMap<Date, URI>> namespaceContext, final String sourcePath) {
+    public YangParserListenerImpl(final Map<String, NavigableMap<Date, URI>> namespaceContext, final String sourcePath) {
         this.namespaceContext = namespaceContext;
         this.sourcePath = sourcePath;
     }
@@ -132,21 +141,19 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
      * the "BaseListener" aspect, which need not be exposed to the user. Maybe
      * factor out a base class into repo.spi?
      *
-     * @param namespaceContext
-     * @param sourcePath
-     * @param walker
-     * @param tree
+     * @param namespaceContext namespaceContext
+     * @param sourcePath sourcePath
+     * @param walker walker
+     * @param tree tree
      * @return new instance of YangParserListenerImpl
      */
-    public static YangParserListenerImpl create(final Map<String, TreeMap<Date, URI>> namespaceContext,
+    public static YangParserListenerImpl create(final Map<String, NavigableMap<Date, URI>> namespaceContext,
             final String sourcePath, final ParseTreeWalker walker, final ParseTree tree) {
         final YangParserListenerImpl ret = new YangParserListenerImpl(namespaceContext, sourcePath);
         walker.walk(ret, tree);
         return ret;
     }
 
-
-
     @Override
     public void enterModule_stmt(final YangParser.Module_stmtContext ctx) {
         moduleName = stringFromNode(ctx);
@@ -159,7 +166,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         String description = null;
         String reference = null;
         for (int i = 0; i < ctx.getChildCount(); i++) {
-            ParseTree child = ctx.getChild(i);
+            final ParseTree child = ctx.getChild(i);
             if (child instanceof Description_stmtContext) {
                 description = stringFromNode(child);
             } else if (child instanceof Reference_stmtContext) {
@@ -192,7 +199,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         String description = null;
         String reference = null;
         for (int i = 0; i < ctx.getChildCount(); i++) {
-            ParseTree child = ctx.getChild(i);
+            final ParseTree child = ctx.getChild(i);
             if (child instanceof Description_stmtContext) {
                 description = stringFromNode(child);
             } else if (child instanceof Reference_stmtContext) {
@@ -216,7 +223,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     @Override
     public void enterBelongs_to_stmt(final YangParser.Belongs_to_stmtContext ctx) {
         final String belongsTo = stringFromNode(ctx);
-        TreeMap<Date, URI> context = namespaceContext.get(belongsTo);
+        final NavigableMap<Date, URI> context = namespaceContext.get(belongsTo);
         final Map.Entry<Date, URI> entry = context.firstEntry();
         // TODO
         // Submodule will contain namespace and revision from module to which it
@@ -318,19 +325,19 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     private void updateRevisionForRevisionStatement(final ParseTree treeNode) {
         final String revisionDateStr = stringFromNode(treeNode);
         try {
-            final Date revisionDate = SIMPLE_DATE_FORMAT.parse(revisionDateStr);
+            final Date revisionDate = revisionFormat.parse(revisionDateStr);
             if ((revisionDate != null) && (this.moduleQName.getRevision().compareTo(revisionDate) < 0)) {
                 this.moduleQName = QName.create(moduleQName.getNamespace(), revisionDate, moduleQName.getLocalName());
                 moduleBuilder.setQNameModule(moduleQName.getModule());
                 setLog("revision", revisionDate.toString());
                 for (int i = 0; i < treeNode.getChildCount(); ++i) {
-                    ParseTree child = treeNode.getChild(i);
+                    final ParseTree child = treeNode.getChild(i);
                     if (child instanceof Reference_stmtContext) {
                         moduleBuilder.setReference(stringFromNode(child));
                     }
                 }
             }
-        } catch (ParseException e) {
+        } catch (final ParseException e) {
             LOG.warn("Failed to parse revision string: {}", revisionDateStr, e);
         }
     }
@@ -339,7 +346,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     public void enterImport_stmt(final Import_stmtContext ctx) {
         final int line = ctx.getStart().getLine();
         final String importName = stringFromNode(ctx);
-        enterLog("import", importName, line);
+        enterLog(IMPORT_STR, importName, line);
 
         String importPrefix = null;
         Date importRevision = null;
@@ -349,10 +356,10 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
             if (treeNode instanceof Prefix_stmtContext) {
                 importPrefix = stringFromNode(treeNode);
             } else if (treeNode instanceof Revision_date_stmtContext) {
-                String importRevisionStr = stringFromNode(treeNode);
+                final String importRevisionStr = stringFromNode(treeNode);
                 try {
-                    importRevision = SIMPLE_DATE_FORMAT.parse(importRevisionStr);
-                } catch (ParseException e) {
+                    importRevision = revisionFormat.parse(importRevisionStr);
+                } catch (final ParseException e) {
                     LOG.warn("Failed to parse import revision-date at line {}: {}", line, importRevisionStr, e);
                 }
             }
@@ -363,14 +370,14 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
 
     @Override
     public void exitImport_stmt(final Import_stmtContext ctx) {
-        exitLog("import");
+        exitLog(IMPORT_STR);
     }
 
     @Override
-    public void enterInclude_stmt(YangParser.Include_stmtContext ctx) {
+    public void enterInclude_stmt(final YangParser.Include_stmtContext ctx) {
         final int line = ctx.getStart().getLine();
         final String includeName = stringFromNode(ctx);
-        enterLog("import", includeName, line);
+        enterLog(IMPORT_STR, includeName, line);
 
         Date includeRevision = null;
         for (int i = 0; i < ctx.getChildCount(); i++) {
@@ -378,8 +385,8 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
             if (treeNode instanceof Revision_date_stmtContext) {
                 final String importRevisionStr = stringFromNode(treeNode);
                 try {
-                    includeRevision = SIMPLE_DATE_FORMAT.parse(importRevisionStr);
-                } catch (ParseException e) {
+                    includeRevision = revisionFormat.parse(importRevisionStr);
+                } catch (final ParseException e) {
                     LOG.warn("Failed to parse import revision-date at line {}: {}", line, importRevisionStr, e);
                 }
             }
@@ -387,7 +394,8 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         moduleBuilder.addInclude(includeName, includeRevision);
     }
 
-    @Override public void exitInclude_stmt(YangParser.Include_stmtContext ctx) {
+    @Override
+    public void exitInclude_stmt(final YangParser.Include_stmtContext ctx) {
         exitLog("include");
     }
 
@@ -399,10 +407,11 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         stack.push();
 
         final SchemaPath targetPath = parseXPathString(augmentPath, line);
-        final AugmentationSchemaBuilder builder = moduleBuilder.addAugment(line, augmentPath, targetPath, augmentOrder++);
+        final AugmentationSchemaBuilder builder = moduleBuilder.addAugment(line, augmentPath, targetPath,
+                augmentOrder++);
 
         for (int i = 0; i < ctx.getChildCount(); i++) {
-            ParseTree child = ctx.getChild(i);
+            final ParseTree child = ctx.getChild(i);
             if (child instanceof Description_stmtContext) {
                 builder.setDescription(stringFromNode(child));
             } else if (child instanceof Reference_stmtContext) {
@@ -508,12 +517,11 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
             } else {
                 QName qname;
                 switch (typeName) {
-                case "union":
-                    qname = BaseTypes.UNION_QNAME;
-                    stack.addNodeToPath(qname);
+                case UNION_STR:
+                    stack.addNodeToPath(BaseTypes.UNION_QNAME);
                     final UnionTypeBuilder unionBuilder = moduleBuilder.addUnionType(line, moduleQName.getModule());
-                    final Builder parent = moduleBuilder.getActualNode();
-                    unionBuilder.setParent(parent);
+                    final Builder parentBuilder = moduleBuilder.getActualNode();
+                    unionBuilder.setParent(parentBuilder);
                     moduleBuilder.enterNode(unionBuilder);
                     break;
                 case "identityref":
@@ -534,23 +542,28 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
                 parent.setTypeQName(typeQName);
                 moduleBuilder.markActualNodeDirty();
             } else {
-                ParserListenerUtils.parseUnknownTypeWithBody(typeBody, parent, typeQName, moduleBuilder,
-                        moduleQName, stack.currentSchemaPath());
+                ParserListenerUtils.parseUnknownTypeWithBody(typeBody, parent, typeQName, moduleBuilder, moduleQName,
+                        stack.currentSchemaPath());
             }
             stack.addNodeToPath(QName.create(moduleQName.getModule(), typeQName.getLocalName()));
         }
     }
 
     /**
-     * Method transforms string representation of yang element (i.e. leaf name, container name etc.) into QName.
-     * The namespace of QName is assigned from parent module same as revision date of module. If String qname parameter
-     * contains ":" the string is evaluated as prefix:name of element. In this case method will look into import map
-     * and extract correct ModuleImport. If such import is not present in import map the method will throw {@link YangParseException}
-     * <br>
-     * If ModuleImport is present but the value of namespace in ModuleImport is <code>null</code> the method will throw {@link YangParseException}
+     * Method transforms string representation of yang element (i.e. leaf name,
+     * container name etc.) into QName. The namespace of QName is assigned from
+     * parent module same as revision date of module. If String qname parameter
+     * contains ":" the string is evaluated as prefix:name of element. In this
+     * case method will look into import map and extract correct ModuleImport.
+     * If such import is not present in import map the method will throw
+     * {@link YangParseException} <br>
+     * If ModuleImport is present but the value of namespace in ModuleImport is
+     * <code>null</code> the method will throw {@link YangParseException}
      *
-     * @param qnameString QName value as String
-     * @param line line in Yang model document where QName occur.
+     * @param qnameString
+     *            QName value as String
+     * @param line
+     *            line in Yang model document where QName occur.
      * @return transformed string qname parameter as QName structure.
      *
      * @throws YangParseException
@@ -570,10 +583,10 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
                 if (imp == null) {
                     LOG.debug("Error in module {} at line {}: No import found with prefix {}", moduleName, line, prefix);
                     throw new YangParseException(moduleName, line, "Error in module " + moduleName
-                        + " No import found with prefix " + prefix + " not found.");
+                            + " No import found with prefix " + prefix + " not found.");
                 }
                 Date revision = imp.getRevision();
-                TreeMap<Date, URI> namespaces = namespaceContext.get(imp.getModuleName());
+                final NavigableMap<Date, URI> namespaces = namespaceContext.get(imp.getModuleName());
                 if (namespaces == null) {
                     throw new YangParseException(moduleName, line, String.format("Imported module %s not found",
                             imp.getModuleName()));
@@ -583,13 +596,14 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
                     revision = namespaces.lastEntry().getKey();
                     namespace = namespaces.lastEntry().getValue();
                 } else {
-                    // FIXME: this lookup does not look right, as we will end up with
-                    //        a qname which does not have a namespace. At any rate we
-                    //        should arrive at a QNameModule!
+                    // FIXME: this lookup does not look right, as we will end up
+                    // with
+                    // a qname which does not have a namespace. At any rate we
+                    // should arrive at a QNameModule!
                     namespace = namespaces.get(revision);
                 }
 
-                final QNameModule mod = QNameModule.cachedReference(QNameModule.create(namespace, revision));
+                final QNameModule mod = QNameModule.create(namespace, revision).intern();
                 qname = QName.create(mod, name);
             }
         }
@@ -599,7 +613,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     @Override
     public void exitType_stmt(final YangParser.Type_stmtContext ctx) {
         final String typeName = stringFromNode(ctx);
-        if ("union".equals(typeName)) {
+        if (UNION_STR.equals(typeName)) {
             moduleBuilder.exitNode();
         }
         exitLog("type", stack.removeNodeFromPath());
@@ -718,7 +732,8 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         stack.push();
 
         final SchemaPath targetPath = parseXPathString(augmentPath, line);
-        final AugmentationSchemaBuilder builder = moduleBuilder.addAugment(line, augmentPath, targetPath, augmentOrder++);
+        final AugmentationSchemaBuilder builder = moduleBuilder.addAugment(line, augmentPath, targetPath,
+                augmentOrder++);
 
         for (int i = 0; i < ctx.getChildCount(); i++) {
             final ParseTree child = ctx.getChild(i);
@@ -816,6 +831,9 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
             } else if (childNode instanceof Key_stmtContext) {
                 final Set<String> key = createListKey((Key_stmtContext) childNode);
                 builder.setKeys(key);
+            } else if (childNode instanceof YangParser.Identifier_stmtContext
+                    && UNION_STR.equals(childNode.getChild(0).toString())) {
+                throw new YangParseException(moduleName, line, "Union statement is not allowed inside a list statement");
             }
         }
     }
@@ -934,16 +952,18 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     @Override
     public void exitIdentifier_stmt(final YangParser.Identifier_stmtContext ctx) {
         moduleBuilder.exitNode();
-        exitLog("unknown-node", stack.removeNodeFromPath());
+        exitLog(UNKNOWN_NODE_STR, stack.removeNodeFromPath());
     }
 
-    @Override public void enterUnknown_statement(final YangParser.Unknown_statementContext ctx) {
+    @Override
+    public void enterUnknown_statement(final YangParser.Unknown_statementContext ctx) {
         handleUnknownNode(ctx.getStart().getLine(), ctx);
     }
 
-    @Override public void exitUnknown_statement(final YangParser.Unknown_statementContext ctx) {
+    @Override
+    public void exitUnknown_statement(final YangParser.Unknown_statementContext ctx) {
         moduleBuilder.exitNode();
-        exitLog("unknown-node", stack.removeNodeFromPath());
+        exitLog(UNKNOWN_NODE_STR, stack.removeNodeFromPath());
     }
 
     @Override
@@ -1052,7 +1072,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         moduleBuilder.enterNode(builder);
 
         for (int i = 0; i < ctx.getChildCount(); i++) {
-            ParseTree child = ctx.getChild(i);
+            final ParseTree child = ctx.getChild(i);
             if (child instanceof Reference_stmtContext) {
                 reference = stringFromNode(child);
             } else if (child instanceof Deviate_not_supported_stmtContext) {
@@ -1073,7 +1093,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         final boolean absolute = !xpathString.isEmpty() && xpathString.charAt(0) == '/';
 
         final List<QName> path = new ArrayList<>();
-        for (String pathElement : SLASH_SPLITTER.split(xpathString)) {
+        for (final String pathElement : SLASH_SPLITTER.split(xpathString)) {
             final Iterator<String> it = COLON_SPLITTER.split(pathElement).iterator();
             final String s = it.next();
             if (it.hasNext()) {
@@ -1108,7 +1128,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         for (int i = 0; i < ctx.getChildCount(); i++) {
             final ParseTree child = ctx.getChild(i);
             if (child instanceof Base_stmtContext) {
-                String baseIdentityName = stringFromNode(child);
+                final String baseIdentityName = stringFromNode(child);
                 builder.setBaseIdentityName(baseIdentityName);
             }
         }
@@ -1142,16 +1162,19 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
 
     private void handleUnknownNode(final int line, final ParseTree ctx) {
         final String nodeParameter = stringFromNode(ctx);
-        enterLog("unknown-node", nodeParameter, line);
+        enterLog(UNKNOWN_NODE_STR, nodeParameter, line);
 
         final String nodeTypeStr = ctx.getChild(0).getText();
         final QName nodeType = parseQName(nodeTypeStr, line);
 
         QName qname = null;
         try {
-            //FIXME: rewrite whole method to handle unknown nodes properly.
-            // This should be bugfix for bug https://bugs.opendaylight.org/show_bug.cgi?id=1539
-            // After this fix bug https://bugs.opendaylight.org/show_bug.cgi?id=1538 MUST be fixed since
+            // FIXME: rewrite whole method to handle unknown nodes properly.
+            // This should be bugfix for bug
+            // https://bugs.opendaylight.org/show_bug.cgi?id=1539
+            // After this fix bug
+            // https://bugs.opendaylight.org/show_bug.cgi?id=1538 MUST be fixed
+            // since
             // they are dependent!!!
             if (Strings.isNullOrEmpty(nodeParameter)) {
                 qname = nodeType;