public List<InferredType> materializeWithoutUnions() {
   List<InferredType> allOptions = new ArrayList<InferredType>();
   for (InferredType branch : unionTypes) {
     allOptions.addAll(branch.materializeWithoutUnions());
   }
   return allOptions;
 }
 List<String> getBases() {
   List<String> tr = new ArrayList<String>();
   for (InferredType subelt : structTypes) {
     tr.addAll(subelt.getBases());
   }
   return tr;
 }
 InferredType duplicate() {
   List<InferredType> newBranches = new ArrayList<InferredType>();
   for (InferredType branch : unionTypes) {
     newBranches.add(branch.duplicate());
   }
   return new UnionType(newBranches);
 }
  /** Parse the given string, return resulting data if appropriate. */
  ParseResult internalParse(
      String s, Map<String, Integer> targetUnionDecisions, boolean mustConsumeStr) {
    boolean hasData = false;
    GenericData.Record gdr = new GenericData.Record(getAvroSchema());
    String currentStr = s;

    for (InferredType subelt : structTypes) {
      if (currentStr.length() == 0) {
        return null;
      }
      ParseResult pr = subelt.internalParse(currentStr, targetUnionDecisions, false);
      if (pr == null) {
        return null;
      }
      if (pr.hasData()) {
        hasData = true;
        gdr.put(subelt.getName(), pr.getData());
      }
      currentStr = pr.getRemainingString();
    }
    if (mustConsumeStr && currentStr.trim().length() != 0) {
      return null;
    }
    return new ParseResult(gdr, hasData, currentStr);
  }
 Map<String, Set<Integer>> findCandidateUnionDecisions() {
   Map<String, Set<Integer>> candidateUnionDecisions = new HashMap<String, Set<Integer>>();
   for (InferredType subelt : structTypes) {
     candidateUnionDecisions.putAll(subelt.findCandidateUnionDecisions());
   }
   return candidateUnionDecisions;
 }
  /** Parse the given string, return resulting data if appropriate. */
  ParseResult internalParse(
      String s, Map<String, Integer> targetUnionDecisions, boolean mustConsumeStr) {
    //
    // If there's no target decision, then go ahead and try all branches.
    //
    if (targetUnionDecisions == null || targetUnionDecisions.get(name) == null) {
      for (InferredType subelt : unionTypes) {
        ParseResult pr = subelt.internalParse(s, targetUnionDecisions, false);
        if (pr != null
            && (!mustConsumeStr
                || (mustConsumeStr && pr.getRemainingString().trim().length() == 0))) {
          return new ParseResult(pr.getData(), pr.hasData(), pr.getRemainingString());
        }
      }
      return null;
    }

    //
    // If there is a target decision, then carry it out.
    //
    InferredType subelt = unionTypes.get(targetUnionDecisions.get(name));
    ParseResult pr = subelt.internalParse(s, targetUnionDecisions, false);
    if (pr != null
        && (!mustConsumeStr || (mustConsumeStr && pr.getRemainingString().trim().length() == 0))) {
      return new ParseResult(pr.getData(), pr.hasData(), pr.getRemainingString());
    }
    return null;
  }
 public double getDescriptionCost() {
   double dc = CARD_COST;
   for (InferredType it : unionTypes) {
     dc += it.getDescriptionCost();
   }
   return dc;
 }
 InferredType duplicate() {
   List<InferredType> newElts = new ArrayList<InferredType>();
   for (InferredType elt : structTypes) {
     newElts.add(elt.duplicate());
   }
   return new StructType(newElts);
 }
 public InferredType hoistUnions() {
   List<InferredType> newStructTypes = new ArrayList<InferredType>();
   for (InferredType it : structTypes) {
     newStructTypes.add(it.hoistUnions());
   }
   return new StructType(newStructTypes);
 }
 public void write(DataOutput out) throws IOException {
   out.write(STRUCT_TYPE);
   out.writeUTF(name);
   out.writeInt(structTypes.size());
   for (InferredType it : structTypes) {
     it.write(out);
   }
 }
 public void write(DataOutput out) throws IOException {
   out.write(UNION_TYPE);
   out.writeUTF(name);
   out.writeInt(unionTypes.size());
   for (InferredType it : unionTypes) {
     it.write(out);
   }
 }
 public String toString() {
   StringBuffer buf = new StringBuffer();
   buf.append("(Union (" + unionTypes.size() + "): ");
   for (InferredType it : unionTypes) {
     buf.append(it.toString() + ", ");
   }
   buf.append(") ");
   return buf.toString();
 }
 public String toString() {
   StringBuffer buf = new StringBuffer();
   buf.append("(Struct: ");
   for (InferredType it : structTypes) {
     buf.append(it.toString() + ", ");
   }
   buf.append(") ");
   return buf.toString();
 }
 public InferredType hoistUnions() {
   List<InferredType> newUnionTypes = new ArrayList<InferredType>();
   for (InferredType it : unionTypes) {
     if (it instanceof UnionType) {
       UnionType subUnion = (UnionType) it;
       for (InferredType it2 : subUnion.unionTypes) {
         newUnionTypes.add(it2.hoistUnions());
       }
     } else {
       newUnionTypes.add(it.hoistUnions());
     }
   }
   return new UnionType(newUnionTypes);
 }
 Schema computeAvroSchema() {
   HashSet<String> observedSchemas = new HashSet<String>();
   List<Schema> fields = new ArrayList<Schema>();
   for (InferredType it : unionTypes) {
     Schema itS = it.getAvroSchema();
     if (itS == null) {
       continue;
     }
     String schemaDesc = itS.toString();
     if (!observedSchemas.contains(schemaDesc)) {
       observedSchemas.add(schemaDesc);
       fields.add(it.getAvroSchema());
     }
   }
   return Schema.createUnion(fields);
 }
 public List<InferredType> materializeWithoutUnions() {
   List<InferredType> newArrays = new ArrayList<InferredType>();
   for (InferredType subtype : bodyType.materializeWithoutUnions()) {
     newArrays.add(new ArrayType(subtype));
   }
   return newArrays;
 }
 public void readFields(DataInput in) throws IOException {
   int numUnionElts = in.readInt();
   this.unionTypes = new ArrayList<InferredType>();
   for (int i = 0; i < numUnionElts; i++) {
     unionTypes.add(InferredType.readType(in));
   }
   this.schema = computeAvroSchema();
 }
 /** Deserialize an unknown InferredType from the given input stream */
 public static InferredType readType(DataInput in) throws IOException {
   InferredType it = null;
   byte b = in.readByte();
   String name = in.readUTF();
   if (b == BASE_TYPE) {
     it = new BaseType(name);
   } else if (b == STRUCT_TYPE) {
     it = new StructType(name);
   } else if (b == ARRAY_TYPE) {
     it = new ArrayType(name);
   } else if (b == UNION_TYPE) {
     it = new UnionType(name);
   } else {
     throw new IOException("No type found: " + b);
   }
   it.readFields(in);
   return it;
 }
 Map<String, Set<Integer>> findCandidateUnionDecisions() {
   HashSet<Integer> curDecisions = new HashSet<Integer>();
   for (int i = 0; i < unionTypes.size(); i++) {
     for (int j = i + 1; j < unionTypes.size(); j++) {
       List<String> iBases = unionTypes.get(i).getBases();
       List<String> jBases = unionTypes.get(j).getBases();
       if (isPrefixOf(iBases, jBases) || isPrefixOf(jBases, iBases)) {
         curDecisions.add(i);
         curDecisions.add(j);
       }
     }
   }
   Map<String, Set<Integer>> candidateUnionDecisions = new HashMap<String, Set<Integer>>();
   for (InferredType subelt : unionTypes) {
     candidateUnionDecisions.putAll(subelt.findCandidateUnionDecisions());
   }
   if (curDecisions.size() > 0) {
     candidateUnionDecisions.put(name, curDecisions);
   }
   return candidateUnionDecisions;
 }
 Schema computeAvroSchema() {
   List<Schema.Field> fields = new ArrayList<Schema.Field>();
   for (InferredType it : structTypes) {
     Schema itS = it.getAvroSchema();
     if (itS == null) {
       continue;
     }
     fields.add(
         new Schema.Field(
             it.getName(), it.getAvroSchema(), it.getDocString(), it.getDefaultValue()));
   }
   Schema s = Schema.createRecord(name, "RECORD", "", false);
   s.setFields(fields);
   return s;
 }
  /** Parse the given string, return resulting data if appropriate. */
  ParseResult internalParse(
      String s, Map<String, Integer> targetUnionDecisions, boolean mustConsumeStr) {
    boolean hasData = false;
    Schema localSchema = getAvroSchema();
    GenericData.Array gda = new GenericData.Array(5, localSchema);
    Map<String, Integer> curUnionDecisions = new HashMap<String, Integer>();
    String currentStr = s;

    while (true) {
      ParseResult pr = bodyType.internalParse(currentStr, targetUnionDecisions, false);
      if (pr == null) {
        break;
      }
      assert (pr.hasData());

      gda.add(pr.getData());
      currentStr = pr.getRemainingString();
    }
    if (mustConsumeStr && currentStr.trim().length() != 0) {
      return null;
    }
    return new ParseResult(gda, true, currentStr);
  }
 public String toString() {
   return "(Array: " + bodyType.toString() + ") ";
 }
 Schema computeAvroSchema() {
   return Schema.createArray(bodyType.getAvroSchema());
 }
 public double getDescriptionCost() {
   return CARD_COST + bodyType.getDescriptionCost();
 }
 Map<String, Set<Integer>> findCandidateUnionDecisions() {
   return bodyType.findCandidateUnionDecisions();
 }
 List<String> getBases() {
   return bodyType.getBases();
 }
 public void readFields(DataInput in) throws IOException {
   bodyType = InferredType.readType(in);
   this.schema = computeAvroSchema();
 }
 public void write(DataOutput out) throws IOException {
   out.write(ARRAY_TYPE);
   out.writeUTF(name);
   bodyType.write(out);
 }
 public InferredType hoistUnions() {
   return new ArrayType(bodyType.hoistUnions());
 }