BUG-868: do not use InstanceIdentifier constructor
[yangtools.git] / yang / yang-parser-impl / src / main / java / org / opendaylight / yangtools / yang / parser / impl / YangParserImpl.java
index d0af63da9b88f8babcf20de1755cb0cefb7178db..b444b78d220456b148f74f9cde65e2bce7180b34 100644 (file)
@@ -7,24 +7,28 @@
 package org.opendaylight.yangtools.yang.parser.impl;
 
 import static com.google.common.base.Preconditions.checkNotNull;
-import static org.opendaylight.yangtools.yang.parser.util.ParserUtils.fillAugmentTarget;
-import static org.opendaylight.yangtools.yang.parser.util.ParserUtils.findBaseIdentity;
-import static org.opendaylight.yangtools.yang.parser.util.ParserUtils.findModuleFromBuilders;
-import static org.opendaylight.yangtools.yang.parser.util.ParserUtils.findModuleFromContext;
-import static org.opendaylight.yangtools.yang.parser.util.ParserUtils.findSchemaNode;
-import static org.opendaylight.yangtools.yang.parser.util.ParserUtils.findSchemaNodeInModule;
-import static org.opendaylight.yangtools.yang.parser.util.ParserUtils.processAugmentation;
-import static org.opendaylight.yangtools.yang.parser.util.ParserUtils.setNodeAddedByUses;
-import static org.opendaylight.yangtools.yang.parser.util.ParserUtils.wrapChildNode;
-import static org.opendaylight.yangtools.yang.parser.util.ParserUtils.wrapChildNodes;
-import static org.opendaylight.yangtools.yang.parser.util.ParserUtils.wrapGroupings;
-import static org.opendaylight.yangtools.yang.parser.util.ParserUtils.wrapTypedefs;
-import static org.opendaylight.yangtools.yang.parser.util.ParserUtils.wrapUnknownNodes;
-import static org.opendaylight.yangtools.yang.parser.util.TypeUtils.resolveType;
-import static org.opendaylight.yangtools.yang.parser.util.TypeUtils.resolveTypeUnion;
-import static org.opendaylight.yangtools.yang.parser.util.TypeUtils.resolveTypeUnionWithContext;
-import static org.opendaylight.yangtools.yang.parser.util.TypeUtils.resolveTypeWithContext;
+import static org.opendaylight.yangtools.yang.parser.builder.impl.BuilderUtils.fillAugmentTarget;
+import static org.opendaylight.yangtools.yang.parser.builder.impl.BuilderUtils.findBaseIdentity;
+import static org.opendaylight.yangtools.yang.parser.builder.impl.BuilderUtils.findModuleFromBuilders;
+import static org.opendaylight.yangtools.yang.parser.builder.impl.BuilderUtils.findModuleFromContext;
+import static org.opendaylight.yangtools.yang.parser.builder.impl.BuilderUtils.findSchemaNode;
+import static org.opendaylight.yangtools.yang.parser.builder.impl.BuilderUtils.findSchemaNodeInModule;
+import static org.opendaylight.yangtools.yang.parser.builder.impl.BuilderUtils.processAugmentation;
+import static org.opendaylight.yangtools.yang.parser.builder.impl.BuilderUtils.setNodeAddedByUses;
+import static org.opendaylight.yangtools.yang.parser.builder.impl.BuilderUtils.wrapChildNode;
+import static org.opendaylight.yangtools.yang.parser.builder.impl.BuilderUtils.wrapChildNodes;
+import static org.opendaylight.yangtools.yang.parser.builder.impl.BuilderUtils.wrapGroupings;
+import static org.opendaylight.yangtools.yang.parser.builder.impl.BuilderUtils.wrapTypedefs;
+import static org.opendaylight.yangtools.yang.parser.builder.impl.BuilderUtils.wrapUnknownNodes;
+import static org.opendaylight.yangtools.yang.parser.builder.impl.TypeUtils.resolveType;
+import static org.opendaylight.yangtools.yang.parser.builder.impl.TypeUtils.resolveTypeUnion;
+import static org.opendaylight.yangtools.yang.parser.builder.impl.TypeUtils.resolveTypeUnionWithContext;
+import static org.opendaylight.yangtools.yang.parser.builder.impl.TypeUtils.resolveTypeWithContext;
 
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.HashBiMap;
+import com.google.common.io.ByteSource;
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
@@ -41,7 +45,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.TreeMap;
-
+import javax.annotation.concurrent.Immutable;
 import org.antlr.v4.runtime.ANTLRInputStream;
 import org.antlr.v4.runtime.CommonTokenStream;
 import org.antlr.v4.runtime.tree.ParseTree;
@@ -50,6 +54,7 @@ import org.opendaylight.yangtools.antlrv4.code.gen.YangLexer;
 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser;
 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.YangContext;
 import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.QNameModule;
 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.ExtensionDefinition;
@@ -67,43 +72,45 @@ import org.opendaylight.yangtools.yang.parser.builder.api.AugmentationTargetBuil
 import org.opendaylight.yangtools.yang.parser.builder.api.Builder;
 import org.opendaylight.yangtools.yang.parser.builder.api.DataNodeContainerBuilder;
 import org.opendaylight.yangtools.yang.parser.builder.api.DataSchemaNodeBuilder;
+import org.opendaylight.yangtools.yang.parser.builder.api.ExtensionBuilder;
 import org.opendaylight.yangtools.yang.parser.builder.api.GroupingBuilder;
 import org.opendaylight.yangtools.yang.parser.builder.api.SchemaNodeBuilder;
 import org.opendaylight.yangtools.yang.parser.builder.api.TypeAwareBuilder;
 import org.opendaylight.yangtools.yang.parser.builder.api.TypeDefinitionBuilder;
+import org.opendaylight.yangtools.yang.parser.builder.api.UnknownSchemaNodeBuilder;
 import org.opendaylight.yangtools.yang.parser.builder.api.UsesNodeBuilder;
+import org.opendaylight.yangtools.yang.parser.builder.impl.BuilderUtils;
 import org.opendaylight.yangtools.yang.parser.builder.impl.ChoiceBuilder;
 import org.opendaylight.yangtools.yang.parser.builder.impl.ChoiceCaseBuilder;
 import org.opendaylight.yangtools.yang.parser.builder.impl.DeviationBuilder;
-import org.opendaylight.yangtools.yang.parser.builder.impl.ExtensionBuilder;
+import org.opendaylight.yangtools.yang.parser.builder.impl.GroupingUtils;
 import org.opendaylight.yangtools.yang.parser.builder.impl.IdentitySchemaNodeBuilder;
 import org.opendaylight.yangtools.yang.parser.builder.impl.IdentityrefTypeBuilder;
 import org.opendaylight.yangtools.yang.parser.builder.impl.ModuleBuilder;
-import org.opendaylight.yangtools.yang.parser.builder.impl.ModuleBuilder.ModuleImpl;
+import org.opendaylight.yangtools.yang.parser.builder.impl.ModuleImpl;
 import org.opendaylight.yangtools.yang.parser.builder.impl.UnionTypeBuilder;
-import org.opendaylight.yangtools.yang.parser.builder.impl.UnknownSchemaNodeBuilder;
-import org.opendaylight.yangtools.yang.parser.util.Comparators;
-import org.opendaylight.yangtools.yang.parser.util.GroupingSort;
-import org.opendaylight.yangtools.yang.parser.util.GroupingUtils;
+import org.opendaylight.yangtools.yang.parser.builder.impl.UnknownSchemaNodeBuilderImpl;
+import org.opendaylight.yangtools.yang.parser.builder.util.Comparators;
 import org.opendaylight.yangtools.yang.parser.util.ModuleDependencySort;
 import org.opendaylight.yangtools.yang.parser.util.NamedByteArrayInputStream;
 import org.opendaylight.yangtools.yang.parser.util.NamedFileInputStream;
 import org.opendaylight.yangtools.yang.parser.util.NamedInputStream;
-import org.opendaylight.yangtools.yang.parser.util.ParserUtils;
 import org.opendaylight.yangtools.yang.parser.util.YangParseException;
-import org.opendaylight.yangtools.yang.validator.YangModelBasicValidator;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.HashBiMap;
-import com.google.common.io.ByteSource;
-
+@Immutable
 public final class YangParserImpl implements YangContextParser {
     private static final Logger LOG = LoggerFactory.getLogger(YangParserImpl.class);
 
     private static final String FAIL_DEVIATION_TARGET = "Failed to find deviation target.";
+    private static final YangParserImpl INSTANCE = new YangParserImpl();
+
+    public static YangParserImpl getInstance() {
+        return INSTANCE;
+    }
+
+
 
     @Override
     @Deprecated
@@ -126,7 +133,7 @@ public final class YangParserImpl implements YangContextParser {
         final String[] fileList = checkNotNull(directory.list(), directory + " not found or is not a directory");
 
         Map<ByteSource, File> sourceToFile = new LinkedHashMap<>();
-        ByteSource mainFileSource = ParserUtils.fileToByteSource(yangFile);
+        ByteSource mainFileSource = BuilderUtils.fileToByteSource(yangFile);
         sourceToFile.put(mainFileSource, yangFile);
 
         for (String fileName : fileList) {
@@ -135,7 +142,7 @@ public final class YangParserImpl implements YangContextParser {
             }
             File dependency = new File(directory, fileName);
             if (dependency.isFile()) {
-                sourceToFile.put(ParserUtils.fileToByteSource(dependency), dependency);
+                sourceToFile.put(BuilderUtils.fileToByteSource(dependency), dependency);
             }
         }
 
@@ -187,7 +194,7 @@ public final class YangParserImpl implements YangContextParser {
             return resolveSchemaContext(Collections.<Module> emptySet());
         }
 
-        Collection<ByteSource> sources = ParserUtils.filesToByteSources(yangFiles);
+        Collection<ByteSource> sources = BuilderUtils.filesToByteSources(yangFiles);
         SchemaContext result = parseSources(sources, context);
         return result;
     }
@@ -196,7 +203,7 @@ public final class YangParserImpl implements YangContextParser {
     @Deprecated
     public Set<Module> parseYangModelsFromStreams(final List<InputStream> yangModelStreams) {
         try {
-            Collection<ByteSource> sources = ParserUtils.streamsToByteSources(yangModelStreams);
+            Collection<ByteSource> sources = BuilderUtils.streamsToByteSources(yangModelStreams);
             return parseSources(sources).getModules();
         } catch (IOException | YangSyntaxErrorException e) {
             throw new YangParseException("Failed to parse yang data", e);
@@ -216,7 +223,7 @@ public final class YangParserImpl implements YangContextParser {
     @Deprecated
     public Set<Module> parseYangModelsFromStreams(final List<InputStream> yangModelStreams, final SchemaContext context) {
         try {
-            Collection<ByteSource> sources = ParserUtils.streamsToByteSources(yangModelStreams);
+            Collection<ByteSource> sources = BuilderUtils.streamsToByteSources(yangModelStreams);
             return parseSources(sources, context).getModules();
         } catch (IOException | YangSyntaxErrorException e) {
             throw new YangParseException("Failed to parse yang data", e);
@@ -325,7 +332,6 @@ public final class YangParserImpl implements YangContextParser {
         Map<ByteSource, ModuleBuilder> sourceToBuilder = resolveSources(sources);
         // sort and check for duplicates
         List<ModuleBuilder> sorted = ModuleDependencySort.sort(sourceToBuilder.values());
-        ParserUtils.setSourceToBuilder(sourceToBuilder);
         Map<String, TreeMap<Date, ModuleBuilder>> modules = orderModules(sorted);
         Map<ModuleBuilder, Module> builderToModule = build(modules);
         Map<ModuleBuilder, ByteSource> builderToSource = HashBiMap.create(sourceToBuilder).inverse();
@@ -349,8 +355,9 @@ public final class YangParserImpl implements YangContextParser {
      *         parsed from stream
      * @throws YangSyntaxErrorException
      */
-    private Map<ByteSource, ModuleBuilder> resolveSources(final Collection<ByteSource> streams) throws IOException,
-    YangSyntaxErrorException {
+    // TODO: remove ByteSource result after removing YangModelParser
+    private Map<ByteSource, ModuleBuilder> resolveSources(final Collection<ByteSource> streams)
+            throws IOException, YangSyntaxErrorException {
         Map<ByteSource, ModuleBuilder> builders = parseSourcesToBuilders(streams);
         Map<ByteSource, ModuleBuilder> result = resolveSubmodules(builders);
         return result;
@@ -368,24 +375,19 @@ public final class YangParserImpl implements YangContextParser {
         YangParserListenerImpl yangModelParser;
         for (Map.Entry<ByteSource, ParseTree> entry : sourceToTree.entrySet()) {
             ByteSource source = entry.getKey();
-            String path = null;
-            InputStream stream = source.openStream();
-            if (stream instanceof NamedInputStream) {
-                path = stream.toString();
-            }
-            try {
-                stream.close();
-            } catch (IOException e) {
-                LOG.warn("Failed to close stream {}", stream);
+            String path = null; // TODO refactor to Optional
+            //TODO refactor so that path can be retrieved without opening stream: NamedInputStream -> NamedByteSource ?
+            try(InputStream stream = source.openStream()) {
+                if (stream instanceof NamedInputStream) {
+                    path = stream.toString();
+                }
             }
-
             yangModelParser = new YangParserListenerImpl(path);
             walker.walk(yangModelParser, entry.getValue());
             ModuleBuilder moduleBuilder = yangModelParser.getModuleBuilder();
+            moduleBuilder.setSource(source);
             sourceToBuilder.put(source, moduleBuilder);
         }
-
-        ParserUtils.setSourceToBuilder(sourceToBuilder);
         return sourceToBuilder;
     }
 
@@ -449,7 +451,7 @@ public final class YangParserImpl implements YangContextParser {
         module.getAugmentBuilders().addAll(submodule.getAugmentBuilders());
         module.getAllAugments().addAll(submodule.getAllAugments());
         module.getChildNodeBuilders().addAll(submodule.getChildNodeBuilders());
-        module.getChildNodes().addAll(submodule.getChildNodes());
+        module.getChildNodes().putAll(submodule.getChildNodes());
         module.getGroupings().addAll(submodule.getGroupings());
         module.getGroupingBuilders().addAll(submodule.getGroupingBuilders());
         module.getTypeDefinitions().addAll(submodule.getTypeDefinitions());
@@ -595,6 +597,11 @@ public final class YangParserImpl implements YangContextParser {
         }
     }
 
+    /**
+     * Mini parser: This parsing context does not validate full YANG module, only
+     * parses header up to the revisions and imports.
+     * @see org.opendaylight.yangtools.yang.parser.impl.util.YangModelDependencyInfo
+     */
     public static YangContext parseStreamWithoutErrorListeners(final InputStream yangStream) {
         YangContext result = null;
         try {
@@ -825,9 +832,8 @@ public final class YangParserImpl implements YangContextParser {
      */
     private void setCorrectAugmentTargetPath(final Map<String, TreeMap<Date, ModuleBuilder>> modules,
             final AugmentationSchemaBuilder augment, final SchemaContext context) {
-        ModuleBuilder module = ParserUtils.getParentModule(augment);
+        ModuleBuilder module = BuilderUtils.getParentModule(augment);
         SchemaPath oldSchemaPath = augment.getTargetPath();
-        List<QName> oldPath = oldSchemaPath.getPath();
         List<QName> newPath = new ArrayList<>();
 
         Builder parent = augment.getParent();
@@ -840,7 +846,7 @@ public final class YangParserImpl implements YangContextParser {
             String prefix;
             QName baseQName = usesParent.getQName();
             if (baseQName == null) {
-                ModuleBuilder m = ParserUtils.getParentModule(usesParent);
+                ModuleBuilder m = BuilderUtils.getParentModule(usesParent);
                 ns = m.getNamespace();
                 revision = m.getRevision();
                 prefix = m.getPrefix();
@@ -850,19 +856,21 @@ public final class YangParserImpl implements YangContextParser {
                 prefix = baseQName.getPrefix();
             }
 
-            for (QName qn : oldSchemaPath.getPath()) {
-                newPath.add(new QName(ns, revision, prefix, qn.getLocalName()));
+            final QNameModule qm = QNameModule.create(ns, revision);
+            for (QName qn : oldSchemaPath.getPathFromRoot()) {
+                newPath.add(QName.create(qm, prefix, qn.getLocalName()));
             }
         } else {
+            Iterable<QName> oldPath = oldSchemaPath.getPathFromRoot();
             for (QName qn : oldPath) {
                 URI ns = module.getNamespace();
                 Date rev = module.getRevision();
                 String localPrefix = qn.getPrefix();
                 if (localPrefix != null && !("".equals(localPrefix))) {
-                    ModuleBuilder currentModule = ParserUtils.findModuleFromBuilders(modules, module, localPrefix,
+                    ModuleBuilder currentModule = BuilderUtils.findModuleFromBuilders(modules, module, localPrefix,
                             augment.getLine());
                     if (currentModule == null) {
-                        Module m = ParserUtils.findModuleFromContext(context, module, localPrefix, augment.getLine());
+                        Module m = BuilderUtils.findModuleFromContext(context, module, localPrefix, augment.getLine());
                         if (m == null) {
                             throw new YangParseException(module.getName(), augment.getLine(), "Module with prefix "
                                     + localPrefix + " not found.");
@@ -918,8 +926,8 @@ public final class YangParserImpl implements YangContextParser {
      */
     private void checkAugmentMandatoryNodes(final Collection<AugmentationSchemaBuilder> augments) {
         for (AugmentationSchemaBuilder augment : augments) {
-            String augmentPrefix = augment.getTargetPath().getPath().get(0).getPrefix();
-            ModuleBuilder module = ParserUtils.getParentModule(augment);
+            String augmentPrefix = augment.getTargetPath().getPathFromRoot().iterator().next().getPrefix();
+            ModuleBuilder module = BuilderUtils.getParentModule(augment);
             String modulePrefix = module.getPrefix();
 
             if (augmentPrefix == null || augmentPrefix.isEmpty() || augmentPrefix.equals(modulePrefix)) {
@@ -1052,8 +1060,8 @@ public final class YangParserImpl implements YangContextParser {
             return true;
         }
 
-        List<QName> targetPath = augment.getTargetPath().getPath();
-        ModuleBuilder targetModule = findTargetModule(targetPath.get(0), module, modules, context, augment.getLine());
+        QName targetPath = augment.getTargetPath().getPathFromRoot().iterator().next();
+        ModuleBuilder targetModule = findTargetModule(targetPath, module, modules, context, augment.getLine());
         if (targetModule == null) {
             throw new YangParseException(module.getModuleName(), augment.getLine(), "Failed to resolve augment "
                     + augment);
@@ -1195,10 +1203,10 @@ public final class YangParserImpl implements YangContextParser {
                             String name = splittedBase[1];
                             ModuleBuilder dependentModule = findTargetModule(prefix, module, modules, context, line);
                             if (dependentModule != null) {
-                                result = ParserUtils.findIdentity(dependentModule.getAddedIdentities(), name);
+                                result = BuilderUtils.findIdentity(dependentModule.getAddedIdentities(), name);
                             }
                         } else {
-                            result = ParserUtils.findIdentity(module.getAddedIdentities(), baseIdentityName);
+                            result = BuilderUtils.findIdentity(module.getAddedIdentities(), baseIdentityName);
                         }
                         identity.setBaseIdentity(result);
                     }
@@ -1225,7 +1233,7 @@ public final class YangParserImpl implements YangContextParser {
             }
         }
         for (UsesNodeBuilder usesNode : allUses) {
-            ModuleBuilder module = ParserUtils.getParentModule(usesNode);
+            ModuleBuilder module = BuilderUtils.getParentModule(usesNode);
             final GroupingBuilder targetGroupingBuilder = GroupingUtils.getTargetGroupingFromModules(usesNode, modules,
                     module);
             if (targetGroupingBuilder == null) {
@@ -1307,7 +1315,7 @@ public final class YangParserImpl implements YangContextParser {
             final SchemaContext context) {
         if (!usesNode.isResolved()) {
             DataNodeContainerBuilder parent = usesNode.getParent();
-            ModuleBuilder module = ParserUtils.getParentModule(parent);
+            ModuleBuilder module = BuilderUtils.getParentModule(parent);
             GroupingBuilder target = GroupingUtils.getTargetGroupingFromModules(usesNode, modules, module);
             if (target == null) {
                 resolveUsesWithContext(usesNode);
@@ -1342,7 +1350,7 @@ public final class YangParserImpl implements YangContextParser {
     private void resolveUsesWithContext(final UsesNodeBuilder usesNode) {
         final int line = usesNode.getLine();
         DataNodeContainerBuilder parent = usesNode.getParent();
-        ModuleBuilder module = ParserUtils.getParentModule(parent);
+        ModuleBuilder module = BuilderUtils.getParentModule(parent);
         SchemaPath parentPath;
         URI ns = null;
         Date rev = null;
@@ -1385,7 +1393,7 @@ public final class YangParserImpl implements YangContextParser {
             setNodeAddedByUses(gb);
         }
 
-        List<UnknownSchemaNodeBuilder> unknownNodes = wrapUnknownNodes(module.getModuleName(), line,
+        List<UnknownSchemaNodeBuilderImpl> unknownNodes = wrapUnknownNodes(module.getModuleName(), line,
                 gd.getUnknownSchemaNodes(), parentPath, ns, rev, pref);
         parent.getUnknownNodes().addAll(unknownNodes);
         for (UnknownSchemaNodeBuilder un : unknownNodes) {
@@ -1497,8 +1505,8 @@ public final class YangParserImpl implements YangContextParser {
         for (DeviationBuilder dev : module.getDeviationBuilders()) {
             int line = dev.getLine();
             SchemaPath targetPath = dev.getTargetPath();
-            List<QName> path = targetPath.getPath();
-            QName q0 = path.get(0);
+            Iterable<QName> path = targetPath.getPathFromRoot();
+            QName q0 = path.iterator().next();
             String prefix = q0.getPrefix();
             if (prefix == null) {
                 prefix = module.getPrefix();
@@ -1544,8 +1552,8 @@ public final class YangParserImpl implements YangContextParser {
         for (DeviationBuilder dev : module.getDeviationBuilders()) {
             int line = dev.getLine();
             SchemaPath targetPath = dev.getTargetPath();
-            List<QName> path = targetPath.getPath();
-            QName q0 = path.get(0);
+            Iterable<QName> path = targetPath.getPathFromRoot();
+            QName q0 = path.iterator().next();
             String prefix = q0.getPrefix();
             if (prefix == null) {
                 prefix = module.getPrefix();
@@ -1591,7 +1599,7 @@ public final class YangParserImpl implements YangContextParser {
      *            current module
      */
     private void processDeviation(final DeviationBuilder dev, final ModuleBuilder dependentModuleBuilder,
-            final List<QName> path, final ModuleBuilder module) {
+            final Iterable<QName> path, final ModuleBuilder module) {
         final int line = dev.getLine();
         Builder currentParent = dependentModuleBuilder;