private static String getStructTypeStringFromAST(ASTNode typeNode)
      throws SemanticException {
    String typeStr = serdeConstants.STRUCT_TYPE_NAME + "<";
    typeNode = (ASTNode) typeNode.getChild(0);
    int children = typeNode.getChildCount();
    if (children <= 0) {
      throw new SemanticException("empty struct not allowed.");
    }
    StringBuilder buffer = new StringBuilder(typeStr);
    Set<String> attributeIdentifiers = new HashSet<>(children);
    for (int i = 0; i < children; i++) {
      ASTNode child = (ASTNode) typeNode.getChild(i);

      String attributeIdentifier = unescapeIdentifier(child.getChild(0).getText());
      if (attributeIdentifiers.contains(attributeIdentifier)) {
        throw new SemanticException(ErrorMsg.AMBIGUOUS_STRUCT_ATTRIBUTE, attributeIdentifier);
      } else {
        attributeIdentifiers.add(attributeIdentifier);
      }

      buffer.append(attributeIdentifier).append(":");
      buffer.append(getTypeStringFromAST((ASTNode) child.getChild(1)));
      if (i < children - 1) {
        buffer.append(",");
      }
    }

    buffer.append(">");
    return buffer.toString();
  }
Get the list of FieldSchema out of the ASTNode.
Additionally, populate the primaryKeys and foreignKeys if any.
ql/src/java/org/apache/hadoop/hive/ql/parse/BaseSemanticAnalyzer.java