*/
package org.opendaylight.yangtools.yang.parser.impl;
-import com.google.common.base.Preconditions;
+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 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;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
import org.antlr.v4.runtime.ANTLRInputStream;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.tree.ParseTree;
import org.antlr.v4.runtime.tree.ParseTreeWalker;
-import org.apache.commons.io.IOUtils;
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.model.api.SchemaContext;
import org.opendaylight.yangtools.yang.model.api.SchemaNode;
import org.opendaylight.yangtools.yang.model.api.SchemaPath;
-import org.opendaylight.yangtools.yang.model.parser.api.YangModelParser;
+import org.opendaylight.yangtools.yang.model.parser.api.YangContextParser;
import org.opendaylight.yangtools.yang.parser.builder.api.AugmentationSchemaBuilder;
import org.opendaylight.yangtools.yang.parser.builder.api.AugmentationTargetBuilder;
import org.opendaylight.yangtools.yang.parser.builder.api.Builder;
import org.opendaylight.yangtools.yang.parser.util.GroupingUtils;
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.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeMap;
-
-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;
-
-public final class YangParserImpl implements YangModelParser {
+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.";
@Override
public Set<Module> parseYangModels(final File yangFile, final File directory) {
+ try {
+ return parseFile(yangFile, directory).getModules();
+ } catch (IOException e) {
+ throw new YangParseException("Failed to parse yang data", e);
+ }
+ }
+
+ @Override
+ public SchemaContext parseFile(final File yangFile, final File directory) throws IOException {
Preconditions.checkState(yangFile.exists(), yangFile + " does not exists");
Preconditions.checkState(directory.exists(), directory + " does not exists");
Preconditions.checkState(directory.isDirectory(), directory + " is not a directory");
final String yangFileName = yangFile.getName();
- final String[] fileList = directory.list();
- checkNotNull(fileList, directory + " not found");
+ final String[] fileList = checkNotNull(directory.list(), directory + " not found or is not a directory");
- FileInputStream yangFileStream = null;
- LinkedHashMap<InputStream, File> streamToFileMap = new LinkedHashMap<>();
- try {
- yangFileStream = new FileInputStream(yangFile);
- streamToFileMap.put(yangFileStream, yangFile);
- } catch (FileNotFoundException e) {
- LOG.warn("Exception while reading yang file: " + yangFile.getName(), e);
- }
+ Map<ByteSource, File> sourceToFile = new LinkedHashMap<>();
+ ByteSource mainFileSource = ParserUtils.fileToByteSource(yangFile);
+ sourceToFile.put(mainFileSource, yangFile);
for (String fileName : fileList) {
if (fileName.equals(yangFileName)) {
continue;
}
File dependency = new File(directory, fileName);
- try {
- if (dependency.isFile()) {
- streamToFileMap.put(new FileInputStream(dependency), dependency);
- }
- } catch (FileNotFoundException e) {
- LOG.warn("Exception while reading yang file: " + fileName, e);
+ if (dependency.isFile()) {
+ sourceToFile.put(ParserUtils.fileToByteSource(dependency), dependency);
}
}
- Map<InputStream, ModuleBuilder> parsedBuilders = parseBuilders(new ArrayList<>(streamToFileMap.keySet()),
- new HashMap<ModuleBuilder, InputStream>());
- ModuleBuilder main = parsedBuilders.get(yangFileStream);
+ Map<ByteSource, ModuleBuilder> sourceToBuilder = parseSourcesToBuilders(sourceToFile.keySet());
+ ModuleBuilder main = sourceToBuilder.get(mainFileSource);
List<ModuleBuilder> moduleBuilders = new ArrayList<>();
moduleBuilders.add(main);
- filterImports(main, new ArrayList<>(parsedBuilders.values()), moduleBuilders);
- Collection<ModuleBuilder> result = resolveSubmodules(moduleBuilders);
+ filterImports(main, new ArrayList<>(sourceToBuilder.values()), moduleBuilders);
+ Collection<ModuleBuilder> resolved = resolveSubmodules(moduleBuilders);
// module builders sorted by dependencies
- ModuleBuilder[] builders = new ModuleBuilder[result.size()];
- result.toArray(builders);
- List<ModuleBuilder> sortedBuilders = ModuleDependencySort.sort(builders);
+ List<ModuleBuilder> sortedBuilders = ModuleDependencySort.sort(resolved);
LinkedHashMap<String, TreeMap<Date, ModuleBuilder>> modules = orderModules(sortedBuilders);
Collection<Module> unsorted = build(modules).values();
- return new LinkedHashSet<>(ModuleDependencySort.sort(unsorted.toArray(new Module[unsorted.size()])));
+ Set<Module> result = new LinkedHashSet<>(
+ ModuleDependencySort.sort(unsorted.toArray(new Module[unsorted.size()])));
+ return resolveSchemaContext(result);
}
@Override
public Set<Module> parseYangModels(final List<File> yangFiles) {
+ return parseFiles(yangFiles).getModules();
+ }
+
+ @Override
+ public SchemaContext parseFiles(final Collection<File> yangFiles) {
Collection<Module> unsorted = parseYangModelsMapped(yangFiles).values();
- return new LinkedHashSet<>(ModuleDependencySort.sort(unsorted.toArray(new Module[unsorted.size()])));
+ Set<Module> sorted = new LinkedHashSet<>(
+ ModuleDependencySort.sort(unsorted.toArray(new Module[unsorted.size()])));
+ return resolveSchemaContext(sorted);
}
@Override
public Set<Module> parseYangModels(final List<File> yangFiles, final SchemaContext context) {
- if (yangFiles == null) {
- return Collections.emptySet();
+ try {
+ return parseFiles(yangFiles, context).getModules();
+ } catch (IOException e) {
+ throw new YangParseException("Failed to parse yang data", e);
}
+ }
- final Map<InputStream, File> inputStreams = new HashMap<>();
- for (final File yangFile : yangFiles) {
- try {
- inputStreams.put(new FileInputStream(yangFile), yangFile);
- } catch (FileNotFoundException e) {
- LOG.warn("Exception while reading yang file: " + yangFile.getName(), e);
- }
+ @Override
+ public SchemaContext parseFiles(final Collection<File> yangFiles, final SchemaContext context) throws IOException {
+ if (yangFiles == null) {
+ return resolveSchemaContext(Collections.<Module> emptySet());
}
- List<InputStream> yangModelStreams = new ArrayList<>(inputStreams.keySet());
- Map<ModuleBuilder, InputStream> builderToStreamMap = new HashMap<>();
- Map<String, TreeMap<Date, ModuleBuilder>> modules = resolveModuleBuilders(yangModelStreams,
- builderToStreamMap, null);
-
- for (InputStream is : inputStreams.keySet()) {
- try {
- is.close();
- } catch (IOException e) {
- LOG.debug("Failed to close stream.");
- }
- }
+ Collection<ByteSource> sources = ParserUtils.filesToByteSources(yangFiles);
+ SchemaContext result = parseSources(sources, context);
+ return result;
+ }
- final Collection<Module> unsorted = buildWithContext(modules, context).values();
- if (context != null) {
- for (Module m : context.getModules()) {
- if (!unsorted.contains(m)) {
- unsorted.add(m);
- }
- }
+ @Override
+ public Set<Module> parseYangModelsFromStreams(final List<InputStream> yangModelStreams) {
+ Collection<ByteSource> sources = ParserUtils.streamsToByteSources(yangModelStreams);
+ try {
+ return parseSources(sources).getModules();
+ } catch (IOException e) {
+ throw new YangParseException("Failed to parse yang data", e);
}
- return new LinkedHashSet<>(ModuleDependencySort.sort(unsorted.toArray(new Module[unsorted.size()])));
}
@Override
- public Set<Module> parseYangModelsFromStreams(final List<InputStream> yangModelStreams) {
- Collection<Module> unsorted = parseYangModelsFromStreamsMapped(yangModelStreams).values();
- return new LinkedHashSet<>(ModuleDependencySort.sort(unsorted.toArray(new Module[unsorted.size()])));
+ public SchemaContext parseSources(Collection<ByteSource> sources) throws IOException {
+ Collection<Module> unsorted = parseYangModelSources(sources).values();
+ Set<Module> sorted = new LinkedHashSet<>(
+ ModuleDependencySort.sort(unsorted.toArray(new Module[unsorted.size()])));
+ return resolveSchemaContext(sorted);
}
@Override
public Set<Module> parseYangModelsFromStreams(final List<InputStream> yangModelStreams, SchemaContext context) {
- if (yangModelStreams == null) {
- return Collections.emptySet();
+ Collection<ByteSource> sources = ParserUtils.streamsToByteSources(yangModelStreams);
+ try {
+ return parseSources(sources, context).getModules();
+ } catch (IOException e) {
+ throw new YangParseException("Failed to parse yang data", e);
+ }
+ }
+
+ @Override
+ public SchemaContext parseSources(Collection<ByteSource> sources, SchemaContext context) throws IOException {
+ if (sources == null) {
+ return resolveSchemaContext(Collections.<Module> emptySet());
}
- final Map<ModuleBuilder, InputStream> builderToStreamMap = new HashMap<>();
- final Map<String, TreeMap<Date, ModuleBuilder>> modules = resolveModuleBuilders(yangModelStreams,
- builderToStreamMap, context);
+ final Map<String, TreeMap<Date, ModuleBuilder>> modules = resolveModuleBuilders(sources, context);
final Set<Module> unsorted = new LinkedHashSet<>(buildWithContext(modules, context).values());
if (context != null) {
for (Module m : context.getModules()) {
}
}
}
- return new LinkedHashSet<>(ModuleDependencySort.sort(unsorted.toArray(new Module[unsorted.size()])));
+ Set<Module> result = new LinkedHashSet<>(
+ ModuleDependencySort.sort(unsorted.toArray(new Module[unsorted.size()])));
+ return resolveSchemaContext(result);
}
@Override
- public Map<File, Module> parseYangModelsMapped(List<File> yangFiles) {
- if (yangFiles == null) {
+ public Map<File, Module> parseYangModelsMapped(Collection<File> yangFiles) {
+ if (yangFiles == null || yangFiles.isEmpty()) {
return Collections.emptyMap();
}
- final Map<InputStream, File> inputStreams = new HashMap<>();
- for (final File yangFile : yangFiles) {
- try {
-
- inputStreams.put(new FileInputStream(yangFile), yangFile);
- } catch (FileNotFoundException e) {
- LOG.warn("Exception while reading yang file: " + yangFile.getName(), e);
- }
+ Map<ByteSource, File> byteSourceToFile = new HashMap<>();
+ for (final File file : yangFiles) {
+ ByteSource source = new ByteSource() {
+ @Override
+ public InputStream openStream() throws IOException {
+ return new NamedFileInputStream(file, file.getPath());
+ }
+ };
+ byteSourceToFile.put(source, file);
}
- List<InputStream> yangModelStreams = new ArrayList<>(inputStreams.keySet());
- Map<ModuleBuilder, InputStream> builderToStreamMap = new HashMap<>();
- Map<String, TreeMap<Date, ModuleBuilder>> modules = resolveModuleBuilders(yangModelStreams, builderToStreamMap,
- null);
-
- for (InputStream is : inputStreams.keySet()) {
- try {
- is.close();
- } catch (IOException e) {
- LOG.debug("Failed to close stream.");
- }
+ Map<ByteSource, Module> byteSourceToModule;
+ try {
+ byteSourceToModule = parseYangModelSources(byteSourceToFile.keySet());
+ } catch (IOException e) {
+ throw new YangParseException("Failed to parse yang data", e);
}
-
Map<File, Module> result = new LinkedHashMap<>();
- Map<ModuleBuilder, Module> builderToModuleMap = build(modules);
- Set<ModuleBuilder> keyset = builderToModuleMap.keySet();
- List<ModuleBuilder> sorted = ModuleDependencySort.sort(keyset.toArray(new ModuleBuilder[keyset.size()]));
- for (ModuleBuilder key : sorted) {
- result.put(inputStreams.get(builderToStreamMap.get(key)), builderToModuleMap.get(key));
+ for (Map.Entry<ByteSource, Module> entry : byteSourceToModule.entrySet()) {
+ result.put(byteSourceToFile.get(entry.getKey()), entry.getValue());
}
return result;
}
- // TODO: fix exception handling
@Override
- public Map<InputStream, Module> parseYangModelsFromStreamsMapped(final List<InputStream> yangModelStreams) {
- if (yangModelStreams == null) {
+ public Map<InputStream, Module> parseYangModelsFromStreamsMapped(final Collection<InputStream> yangModelStreams) {
+ if (yangModelStreams == null || yangModelStreams.isEmpty()) {
return Collections.emptyMap();
}
-
- // copy input streams so that they can be read more than once
- Map<InputStream/*array backed copy */, InputStream/* original for returning*/> arrayBackedToOriginalInputStreams = new HashMap<>();
- for (final InputStream originalIS : yangModelStreams) {
- InputStream arrayBackedIs;
- try {
- arrayBackedIs = NamedByteArrayInputStream.create(originalIS);
- } catch (IOException e) {
- // FIXME: throw IOException here
- throw new IllegalStateException("Can not get yang as String from " + originalIS, e);
- }
- arrayBackedToOriginalInputStreams.put(arrayBackedIs, originalIS);
- }
-
- // it would be better if all code from here used string representation of yang sources instead of input streams
- Map<ModuleBuilder, InputStream> builderToStreamMap = new HashMap<>(); // FIXME: do not modify input parameter
- Map<String, TreeMap<Date, ModuleBuilder>> modules = resolveModuleBuilders(new ArrayList<>(arrayBackedToOriginalInputStreams.keySet()),
- builderToStreamMap,
- null);
-
-
- // TODO move deeper
- for(TreeMap<Date, ModuleBuilder> value : modules.values()) {
- Collection<ModuleBuilder> values = value.values();
- for(ModuleBuilder builder: values) {
- InputStream is = builderToStreamMap.get(builder);
- try {
- is.reset();
- } catch (IOException e) {
- // this cannot happen because it is ByteArrayInputStream
- throw new IllegalStateException("Possible error in code", e);
- }
- String content;
- try {
- content = IOUtils.toString(is);
- } catch (IOException e) {
- // this cannot happen because it is ByteArrayInputStream
- throw new IllegalStateException("Possible error in code", e);
+ Map<ByteSource, InputStream> sourceToStream = new HashMap<>();
+ for (final InputStream stream : yangModelStreams) {
+ ByteSource source = new ByteSource() {
+ @Override
+ public InputStream openStream() throws IOException {
+ return NamedByteArrayInputStream.create(stream);
}
- builder.setSource(content);
- }
+ };
+ sourceToStream.put(source, stream);
}
-
- Map<ModuleBuilder, Module> builderToModuleMap = build(modules);
-
- Set<ModuleBuilder> keyset = builderToModuleMap.keySet();
- List<ModuleBuilder> sorted = ModuleDependencySort.sort(keyset.toArray(new ModuleBuilder[keyset.size()]));
+ Map<ByteSource, Module> sourceToModule;
+ try {
+ sourceToModule = parseYangModelSources(sourceToStream.keySet());
+ } catch (IOException e) {
+ throw new YangParseException("Failed to parse yang data", e);
+ }
Map<InputStream, Module> result = new LinkedHashMap<>();
- for (ModuleBuilder key : sorted) {
- Module value = checkNotNull(builderToModuleMap.get(key), "Cannot get module for %s", key);
- InputStream arrayBackedIS = checkNotNull(builderToStreamMap.get(key), "Cannot get is for %s", key);
- InputStream originalIS = arrayBackedToOriginalInputStreams.get(arrayBackedIS);
- result.put(originalIS, value);
+ for (Map.Entry<ByteSource, Module> entry : sourceToModule.entrySet()) {
+ result.put(sourceToStream.get(entry.getKey()), entry.getValue());
}
return result;
}
return new SchemaContextImpl(modules, identifiersToSources);
}
- // FIXME: why a list is required?
- // FIXME: streamToBuilderMap is output of this method, not input
- private Map<InputStream, ModuleBuilder> parseModuleBuilders(List<InputStream> inputStreams,
- Map<ModuleBuilder, InputStream> streamToBuilderMap) {
- Map<InputStream, ModuleBuilder> modules = parseBuilders(inputStreams, streamToBuilderMap);
- Map<InputStream, ModuleBuilder> result = resolveSubmodules(modules);
+ private Map<ByteSource, Module> parseYangModelSources(final Collection<ByteSource> sources) throws IOException {
+ if (sources == null || sources.isEmpty()) {
+ return Collections.emptyMap();
+ }
+
+ 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();
+ sorted = ModuleDependencySort.sort(builderToModule.keySet());
+
+ Map<ByteSource, Module> result = new LinkedHashMap<>();
+ for (ModuleBuilder moduleBuilder : sorted) {
+ Module value = checkNotNull(builderToModule.get(moduleBuilder), "Cannot get module for %s", moduleBuilder);
+ result.put(builderToSource.get(moduleBuilder), value);
+ }
+
return result;
}
- // FIXME: why a list is required?
- // FIXME: streamToBuilderMap is output of this method, not input
- private Map<InputStream, ModuleBuilder> parseBuilders(List<InputStream> inputStreams,
- Map<ModuleBuilder, InputStream> streamToBuilderMap) {
+ /**
+ * Parse streams and resolve submodules.
+ *
+ * @param streams
+ * collection of streams to parse
+ * @return map, where key is source stream and value is module builder
+ * parsed from stream
+ */
+ private Map<ByteSource, ModuleBuilder> resolveSources(Collection<ByteSource> streams) throws IOException {
+ Map<ByteSource, ModuleBuilder> builders = parseSourcesToBuilders(streams);
+ Map<ByteSource, ModuleBuilder> result = resolveSubmodules(builders);
+ return result;
+ }
+
+ private Map<ByteSource, ModuleBuilder> parseSourcesToBuilders(Collection<ByteSource> sources) throws IOException {
final ParseTreeWalker walker = new ParseTreeWalker();
- final Map<InputStream, ParseTree> trees = parseStreams(inputStreams);
- final Map<InputStream, ModuleBuilder> builders = new LinkedHashMap<>();
+ final Map<ByteSource, ParseTree> sourceToTree = parseYangSources(sources);
+ final Map<ByteSource, ModuleBuilder> sourceToBuilder = new LinkedHashMap<>();
// validate yang
- new YangModelBasicValidator(walker).validate(new ArrayList<>(trees.values()));
+ new YangModelBasicValidator(walker).validate(sourceToTree.values());
YangParserListenerImpl yangModelParser;
- for (Map.Entry<InputStream, ParseTree> entry : trees.entrySet()) {
- InputStream is = entry.getKey();
+ for (Map.Entry<ByteSource, ParseTree> entry : sourceToTree.entrySet()) {
+ ByteSource source = entry.getKey();
String path = null;
- if (is instanceof NamedInputStream) {
- path = is.toString();
+ InputStream stream = source.openStream();
+ if (stream instanceof NamedInputStream) {
+ path = stream.toString();
+ }
+ try {
+ stream.close();
+ } catch (IOException e) {
+ LOG.warn("Failed to close stream {}", stream);
}
+
yangModelParser = new YangParserListenerImpl(path);
walker.walk(yangModelParser, entry.getValue());
ModuleBuilder moduleBuilder = yangModelParser.getModuleBuilder();
-
- // We expect the order of trees and streams has to be the same
- // FIXME: input parameters should be treated as immutable
- streamToBuilderMap.put(moduleBuilder, entry.getKey());
-
- builders.put(entry.getKey(), moduleBuilder);
+ sourceToBuilder.put(source, moduleBuilder);
}
- return builders;
+ return sourceToBuilder;
}
- private Map<InputStream, ModuleBuilder> resolveSubmodules(Map<InputStream, ModuleBuilder> builders) {
- Map<InputStream, ModuleBuilder> modules = new HashMap<>();
+ private Map<ByteSource, ModuleBuilder> resolveSubmodules(Map<ByteSource, ModuleBuilder> builders) {
+ Map<ByteSource, ModuleBuilder> modules = new HashMap<>();
Set<ModuleBuilder> submodules = new HashSet<>();
- for (Map.Entry<InputStream, ModuleBuilder> entry : builders.entrySet()) {
+ for (Map.Entry<ByteSource, ModuleBuilder> entry : builders.entrySet()) {
ModuleBuilder moduleBuilder = entry.getValue();
if (moduleBuilder.isSubmodule()) {
submodules.add(moduleBuilder);
return modules;
}
+ /**
+ * Traverse collection of builders, find builders representing submodule and
+ * add this submodule to its parent module.
+ *
+ * @param builders
+ * collection of builders containing modules and submodules
+ * @return collection of module builders
+ */
private Collection<ModuleBuilder> resolveSubmodules(Collection<ModuleBuilder> builders) {
Collection<ModuleBuilder> modules = new HashSet<>();
Set<ModuleBuilder> submodules = new HashSet<>();
module.getAllUnknownNodes().addAll(submodule.getAllUnknownNodes());
}
- // FIXME: why a list is required?
- // FIXME: streamToBuilderMap is output of this method, not input
- private Map<String, TreeMap<Date, ModuleBuilder>> resolveModuleBuilders(final List<InputStream> yangFileStreams,
- final Map<ModuleBuilder, InputStream> streamToBuilderMap, final SchemaContext context) {
- Map<InputStream, ModuleBuilder> parsedBuilders = parseModuleBuilders(yangFileStreams, streamToBuilderMap);
+ private Map<String, TreeMap<Date, ModuleBuilder>> resolveModuleBuilders(
+ final Collection<ByteSource> yangFileStreams, final SchemaContext context) throws IOException {
+ Map<ByteSource, ModuleBuilder> parsedBuilders = resolveSources(yangFileStreams);
ModuleBuilder[] builders = new ModuleBuilder[parsedBuilders.size()];
parsedBuilders.values().toArray(builders);
return result;
}
- private void filterImports(ModuleBuilder main, List<ModuleBuilder> other, List<ModuleBuilder> filtered) {
+ /**
+ * Find {@code main} dependencies from {@code other} and add them to
+ * {@code filtered}.
+ *
+ * @param main
+ * main yang module
+ * @param other
+ * all loaded modules
+ * @param filtered
+ * collection to fill up
+ */
+ private void filterImports(ModuleBuilder main, Collection<ModuleBuilder> other, Collection<ModuleBuilder> filtered) {
Set<ModuleImport> imports = main.getModuleImports();
// if this is submodule, add parent to filtered and pick its imports
}
}
- // FIXME: why a list is required?
- private Map<InputStream, ParseTree> parseStreams(final List<InputStream> yangStreams) {
- final Map<InputStream, ParseTree> trees = new HashMap<>();
- for (InputStream yangStream : yangStreams) {
- trees.put(yangStream, parseStream(yangStream));
+ private Map<ByteSource, ParseTree> parseYangSources(final Collection<ByteSource> sources) throws IOException {
+ final Map<ByteSource, ParseTree> trees = new HashMap<>();
+ for (ByteSource source : sources) {
+ trees.put(source, parseYangSource(source));
}
return trees;
}
- private ParseTree parseStream(final InputStream yangStream) {
+ private ParseTree parseYangSource(final ByteSource source) throws IOException {
ParseTree result = null;
+ InputStream stream = null;
try {
- final ANTLRInputStream input = new ANTLRInputStream(yangStream);
+ stream = source.openStream();
+ final ANTLRInputStream input = new ANTLRInputStream(stream);
final YangLexer lexer = new YangLexer(input);
final CommonTokenStream tokens = new CommonTokenStream(lexer);
final YangParser parser = new YangParser(tokens);
parser.addErrorListener(errorListener);
result = parser.yang();
errorListener.validate();
- } catch (IOException e) {
- // TODO: fix this ASAP
- LOG.warn("Exception while reading yang file: " + yangStream, e);
+ } finally {
+ if (stream != null) {
+ try {
+ stream.close();
+ } catch (IOException e) {
+ LOG.warn("Failed to close stream {}", stream);
+ }
+ }
}
return result;
}