@args com.linkedin.pegasus.generator.spec.UnionTemplateSpec union, java.util.Map<String, String> memberKeyToTypeName, org.coursera.courier.swift.SwiftSyntax syntax, org.coursera.courier.swift.SwiftyJSON swifty
@import com.linkedin.pegasus.generator.spec.UnionTemplateSpec.Member

@{ String className = syntax.escapeKeyword(union.getClassName()) }

public static func readJSON(json: JSON) throws -> @className {
  switch json["typeName"].stringValue {
    @for(Member member: union.getMembers()) {
    @{ String unionMemberName = syntax.toUnionMemberName(member.getClassTemplateSpec()) }
      case "@(memberKeyToTypeName.get(member.getSchema().getUnionMemberKey()))":
        return .@(unionMemberName)(@swifty.toGetAccessor("json[\"definition\"]", member))
    }
    default:
      if let unknownDict = json.dictionaryObject {
        return .UNKNOWN$(unknownDict)
      } else {
        throw ReadError(cause: "Typed Definition Union must be a JSON object.")
      }
  }
}

public func writeData() -> [String: AnyObject] {
  switch self {
    @for(Member member: union.getMembers()) {
    @{ String unionMemberName = syntax.toUnionMemberName(member.getClassTemplateSpec()) }
      case .@(unionMemberName)(let member):
        return ["typeName": "@(memberKeyToTypeName.get(member.getSchema().getUnionMemberKey()))", "definition": @swifty.toSetAccessor("member", member)];
    }
    case .UNKNOWN$(let dict):
      return dict
  }
}
