private Schema loadFromDirectories(List<Path> directories) throws IOException { final Deque<String> protos = new ArrayDeque<>(this.protos); if (protos.isEmpty()) { for (final Path directory : directories) { Files.walkFileTree( directory, new SimpleFileVisitor<Path>() { @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { protos.add(directory.relativize(file).toString()); return FileVisitResult.CONTINUE; } }); } } Map<String, ProtoFile> loaded = new LinkedHashMap<>(); while (!protos.isEmpty()) { String proto = protos.removeFirst(); if (loaded.containsKey(proto)) { continue; } ProtoFileElement element = null; for (Path directory : directories) { Source source = source(proto, directory); if (source == null) { continue; } try { Location location = Location.get(directory.toString(), proto); String data = Okio.buffer(source).readUtf8(); element = ProtoParser.parse(location, data); } catch (IOException e) { throw new IOException("Failed to load " + proto + " from " + directory, e); } finally { source.close(); } } if (element == null) { throw new FileNotFoundException("Failed to locate " + proto + " in " + sources); } ProtoFile protoFile = ProtoFile.get(element); loaded.put(proto, protoFile); // Queue dependencies to be loaded. for (String importPath : element.imports()) { protos.addLast(importPath); } } return new Linker(loaded.values()).link(); }
public Schema load() throws IOException { ImmutableList<Path> directories = this.directories.build(); if (directories.isEmpty()) { throw new IllegalStateException("No directories added."); } Deque<Path> protos = new ArrayDeque<>(this.protos.build()); if (protos.isEmpty()) { // TODO traverse all files in every directory. } Map<Path, ProtoFile> loaded = new LinkedHashMap<>(); while (!protos.isEmpty()) { Path proto = protos.removeFirst(); if (loaded.containsKey(proto)) { continue; } ProtoFileElement element = null; for (Path directory : directories) { if (proto.isAbsolute() && !proto.startsWith(directory)) { continue; } Path resolvedPath = directory.resolve(proto); if (Files.exists(resolvedPath)) { Location location = Location.get(directory.toString(), proto.toString()); try (Source source = Okio.source(resolvedPath)) { String data = Okio.buffer(source).readUtf8(); element = ProtoParser.parse(location, data); } catch (IOException e) { throw new IOException("Failed to load " + proto, e); } break; } } if (element == null) { throw new FileNotFoundException("Failed to locate " + proto + " in " + directories); } ProtoFile protoFile = ProtoFile.get(element); loaded.put(proto, protoFile); // Queue dependencies to be loaded. FileSystem fs = proto.getFileSystem(); for (String importPath : element.imports()) { protos.addLast(fs.getPath(importPath)); } } return new Linker(loaded.values()).link(); }