Beispiel #1
0
  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();
  }
Beispiel #2
0
  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();
  }