public static void write()

in library-model/library-model-generator/src/main/java/com/uber/nullaway/libmodel/StubxWriter.java [41:152]


  public static void write(
      DataOutputStream out,
      Map<String, String> importedAnnotations,
      Map<String, Set<String>> packageAnnotations,
      Map<String, Set<String>> typeAnnotations,
      Map<String, MethodAnnotationsRecord> methodRecords,
      Set<String> nullMarkedClasses,
      Map<String, Set<Integer>> nullableUpperBounds)
      throws IOException {
    // File format version/magic number
    out.writeInt(VERSION_1_FILE_MAGIC_NUMBER);
    // Followed by the number of string dictionary entries
    int numStringEntries = 0;
    Map<String, Integer> encodingDictionary = new LinkedHashMap<>();
    List<String> strings = new ArrayList<String>();
    ImmutableList<Collection<String>> keysets =
        ImmutableList.of(
            importedAnnotations.values(),
            packageAnnotations.keySet(),
            typeAnnotations.keySet(),
            methodRecords.keySet(),
            nullMarkedClasses,
            nullableUpperBounds.keySet());
    for (Collection<String> keyset : keysets) {
      for (String key : keyset) {
        if (encodingDictionary.containsKey(key)) {
          continue;
        }
        strings.add(key);
        encodingDictionary.put(key, numStringEntries);
        ++numStringEntries;
      }
    }
    out.writeInt(numStringEntries);
    // Followed by the entries themselves
    for (String s : strings) {
      out.writeUTF(s);
    }
    // Followed by the number of encoded package annotation records
    int packageAnnotationSize = 0;
    for (Map.Entry<String, Set<String>> entry : packageAnnotations.entrySet()) {
      packageAnnotationSize += entry.getValue().size();
    }
    out.writeInt(packageAnnotationSize);
    // Followed by those records as pairs of ints pointing into the dictionary
    for (Map.Entry<String, Set<String>> entry : packageAnnotations.entrySet()) {
      for (String annot : entry.getValue()) {
        out.writeInt(encodingDictionary.get(entry.getKey()));
        out.writeInt(encodingDictionary.get(importedAnnotations.get(annot)));
      }
    }
    // Followed by the number of encoded type annotation records
    int typeAnnotationSize = 0;
    for (Map.Entry<String, Set<String>> entry : typeAnnotations.entrySet()) {
      typeAnnotationSize += entry.getValue().size();
    }
    out.writeInt(typeAnnotationSize);
    // Followed by those records as pairs of ints pointing into the dictionary
    for (Map.Entry<String, Set<String>> entry : typeAnnotations.entrySet()) {
      for (String annot : entry.getValue()) {
        out.writeInt(encodingDictionary.get(entry.getKey()));
        out.writeInt(encodingDictionary.get(importedAnnotations.get(annot)));
      }
    }
    // Followed by the number of encoded method return/declaration annotation records
    int methodAnnotationSize = 0;
    int methodArgumentRecordsSize = 0;
    for (Map.Entry<String, MethodAnnotationsRecord> entry : methodRecords.entrySet()) {
      methodAnnotationSize += entry.getValue().methodAnnotations().size();
      methodArgumentRecordsSize += entry.getValue().argumentAnnotations().size();
    }
    out.writeInt(methodAnnotationSize);
    // Followed by those records as pairs of ints pointing into the dictionary
    for (Map.Entry<String, MethodAnnotationsRecord> entry : methodRecords.entrySet()) {
      for (String annot : entry.getValue().methodAnnotations()) {
        out.writeInt(encodingDictionary.get(entry.getKey()));
        out.writeInt(encodingDictionary.get(importedAnnotations.get(annot)));
      }
    }
    // Followed by the number of encoded method argument annotation records
    out.writeInt(methodArgumentRecordsSize);
    // Followed by those records as a triplet of ints ( 0 and 2 point in the dictionary, 1 is the
    //  argument position)
    for (Map.Entry<String, MethodAnnotationsRecord> entry : methodRecords.entrySet()) {
      for (Map.Entry<Integer, ImmutableSet<String>> argEntry :
          entry.getValue().argumentAnnotations().entrySet()) {
        for (String annot : argEntry.getValue()) {
          out.writeInt(encodingDictionary.get(entry.getKey()));
          out.writeInt(argEntry.getKey());
          out.writeInt(encodingDictionary.get(importedAnnotations.get(annot)));
        }
      }
    }
    // Followed by the number of NullMarked Classes
    out.writeInt(nullMarkedClasses.size());
    // Followed by the null marked class records from the dictionary
    for (String entry : nullMarkedClasses) {
      out.writeInt(encodingDictionary.get(entry));
    }
    // Followed by the number of nullable upper bounds records
    out.writeInt(nullableUpperBounds.size());
    for (Map.Entry<String, Set<Integer>> entry : nullableUpperBounds.entrySet()) {
      // Followed by the number of parameters with nullable upper bound
      Set<Integer> parameters = entry.getValue();
      out.writeInt(parameters.size());
      for (Integer parameter : parameters) {
        // Followed by the nullable upper bound record as a pair of integers
        out.writeInt(encodingDictionary.get(entry.getKey()));
        out.writeInt(parameter);
      }
    }
  }