package com.chenyang.druid.sql.ast;

import com.chenyang.druid.DbType;
import com.chenyang.druid.sql.SQLUtils;
import com.chenyang.druid.sql.dialect.dm.ast.DMSQLObject;
import com.chenyang.druid.sql.dialect.gauss.ast.GaussSQLObject;
import com.chenyang.druid.sql.dialect.greenplum.ast.GPSQLObject;
import com.chenyang.druid.sql.dialect.kingbase.KingbaseSQLObject;
import com.chenyang.druid.sql.dialect.mysql.ast.MySqlObject;
import com.chenyang.druid.sql.dialect.oracle.ast.OracleSQLObject;
import com.chenyang.druid.sql.dialect.postgresql.ast.PGSQLObject;
import com.chenyang.druid.sql.visitor.SQLASTVisitor;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public abstract class SQLObjectImpl implements SQLObject {
   protected SQLObject parent;
   protected Map<String, Object> attributes;
   protected SQLCommentHint hint;
   protected int sourceLine;
   protected int sourceColumn;

   public final void accept(SQLASTVisitor visitor) {
      if (visitor == null) {
         throw new IllegalArgumentException();
      } else {
         visitor.preVisit(this);
         this.accept0(visitor);
         visitor.postVisit(this);
      }
   }

   protected abstract void accept0(SQLASTVisitor var1);

   protected final void acceptChild(SQLASTVisitor visitor, List<? extends SQLObject> children) {
      if (children != null) {
         for(int i = 0; i < children.size(); ++i) {
            this.acceptChild(visitor, (SQLObject)children.get(i));
         }

      }
   }

   protected final void acceptChild(SQLASTVisitor visitor, SQLObject child) {
      if (child != null) {
         child.accept(visitor);
      }
   }

   public void output(StringBuffer buf) {
      this.output((Appendable)buf);
   }

   public void output(Appendable buf) {
      DbType dbType = null;
      if (this instanceof OracleSQLObject) {
         dbType = DbType.oracle;
      } else if (this instanceof MySqlObject) {
         dbType = DbType.mysql;
      } else if (this instanceof PGSQLObject) {
         dbType = DbType.postgresql;
      } else if (this instanceof GPSQLObject) {
         dbType = DbType.greenplum;
      } else if (this instanceof GaussSQLObject) {
         dbType = DbType.gauss;
      } else if (this instanceof SQLDbTypedObject) {
         dbType = ((SQLDbTypedObject)this).getDbType();
      } else if (this instanceof DMSQLObject) {
         dbType = DbType.dm;
      } else if (this instanceof KingbaseSQLObject) {
         dbType = DbType.kingbase;
      }

      if (dbType == null) {
         dbType = SQLUtils.getDbTypteByParent(this);
      }

      this.accept(SQLUtils.createOutputVisitor(buf, dbType));
   }

   public String toString() {
      StringBuffer buf = new StringBuffer();
      this.output(buf);
      return buf.toString();
   }

   public SQLObject getParent() {
      return this.parent;
   }

   public void setParent(SQLObject parent) {
      this.parent = parent;
   }

   public Map<String, Object> getAttributes() {
      if (this.attributes == null) {
         this.attributes = new HashMap(1);
      }

      return this.attributes;
   }

   public Object getAttribute(String name) {
      return this.attributes == null ? null : this.attributes.get(name);
   }

   public boolean containsAttribute(String name) {
      return this.attributes == null ? false : this.attributes.containsKey(name);
   }

   public void putAttribute(String name, Object value) {
      if (this.attributes == null) {
         this.attributes = new HashMap(1);
      }

      this.attributes.put(name, value);
   }

   public void putAttribute(String name) {
      if (this.attributes == null) {
         this.attributes = new HashMap(1);
      }

      this.attributes.put(name, true);
   }

   public void removeAttribute(String name) {
      if (name != null && name.length() != 0) {
         this.attributes.remove(name);
      }
   }

   public Map<String, Object> getAttributesDirect() {
      return this.attributes;
   }

   public void addBeforeComment(String comment) {
      if (comment != null) {
         if (this.attributes == null) {
            this.attributes = new HashMap(1);
         }

         List<String> comments = (List)this.attributes.get("rowFormat.before_comment");
         if (comments == null) {
            comments = new ArrayList(2);
            this.attributes.put("rowFormat.before_comment", comments);
         }

         ((List)comments).add(comment);
      }
   }

   public void addBeforeComment(List<String> comments) {
      if (this.attributes == null) {
         this.attributes = new HashMap(1);
      }

      List<String> attrComments = (List)this.attributes.get("rowFormat.before_comment");
      if (attrComments == null) {
         this.attributes.put("rowFormat.before_comment", comments);
      } else {
         attrComments.addAll(comments);
      }

   }

   public List<String> getBeforeCommentsDirect() {
      return this.attributes == null ? null : (List)this.attributes.get("rowFormat.before_comment");
   }

   public void addAfterComment(String comment) {
      if (this.attributes == null) {
         this.attributes = new HashMap(1);
      }

      List<String> comments = (List)this.attributes.get("rowFormat.after_comment");
      if (comments == null) {
         comments = new ArrayList(2);
         this.attributes.put("rowFormat.after_comment", comments);
      }

      ((List)comments).add(comment);
   }

   public void addAfterComment(List<String> comments) {
      if (comments != null) {
         if (this.attributes == null) {
            this.attributes = new HashMap(1);
         }

         List<String> attrComments = (List)this.attributes.get("rowFormat.after_comment");
         if (attrComments == null) {
            this.attributes.put("rowFormat.after_comment", comments);
         } else {
            attrComments.addAll(comments);
         }

      }
   }

   public List<String> getAfterCommentsDirect() {
      return this.attributes == null ? null : (List)this.attributes.get("rowFormat.after_comment");
   }

   public boolean hasBeforeComment() {
      if (this.attributes == null) {
         return false;
      } else {
         List<String> comments = (List)this.attributes.get("rowFormat.before_comment");
         if (comments == null) {
            return false;
         } else {
            return !comments.isEmpty();
         }
      }
   }

   public boolean hasAfterComment() {
      if (this.attributes == null) {
         return false;
      } else {
         List<String> comments = (List)this.attributes.get("rowFormat.after_comment");
         if (comments == null) {
            return false;
         } else {
            return !comments.isEmpty();
         }
      }
   }

   public SQLObject clone() {
      throw new UnsupportedOperationException(this.getClass().getName());
   }

   public SQLDataType computeDataType() {
      return null;
   }

   public int getSourceLine() {
      return this.sourceLine;
   }

   public void setSourceLine(int sourceLine) {
      this.sourceLine = sourceLine;
   }

   public int getSourceColumn() {
      return this.sourceColumn;
   }

   public void setSourceColumn(int sourceColumn) {
      this.sourceColumn = sourceColumn;
   }

   public SQLCommentHint getHint() {
      return this.hint;
   }

   public void setHint(SQLCommentHint hint) {
      this.hint = hint;
   }
}
