// Path: octopus-core/src/main/java/kr/co/bitnine/octopus/sql/OctopusSqlObjectPrivileges.java
// static class OctopusSqlGrantObjPrivs extends OctopusSqlObjectPrivileges {
//     OctopusSqlGrantObjPrivs(List<ObjectPrivilege> objPrivs, String[] objName, List<String> grantees) {
//         super(objPrivs, objName, grantees);
//     }
// 
//     @Override
//     public Type getType() {
//         return Type.GRANT_OBJ_PRIVS;
//     }
// }
// 
// Path: octopus-core/src/main/java/kr/co/bitnine/octopus/sql/OctopusSqlObjectPrivileges.java
// static class OctopusSqlRevokeObjPrivs extends OctopusSqlObjectPrivileges {
//     OctopusSqlRevokeObjPrivs(List<ObjectPrivilege> objPrivs, String[] objName, List<String> revokees) {
//         super(objPrivs, objName, revokees);
//     }
// 
//     @Override
//     public Type getType() {
//         return Type.REVOKE_OBJ_PRIVS;
//     }
// }


import static kr.co.bitnine.octopus.sql.OctopusSqlSystemPrivileges.OctopusSqlGrantSysPrivs;
import static kr.co.bitnine.octopus.sql.OctopusSqlSystemPrivileges.OctopusSqlRevokeSysPrivs;
import kr.co.bitnine.octopus.meta.privilege.ObjectPrivilege;
import kr.co.bitnine.octopus.meta.privilege.SystemPrivilege;
import kr.co.bitnine.octopus.postgres.executor.TupleSet;
import org.antlr.v4.runtime.ANTLRInputStream;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.ParserRuleContext;
import org.antlr.v4.runtime.tree.ParseTreeWalker;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import static kr.co.bitnine.octopus.sql.OctopusSqlObjectPrivileges.OctopusSqlGrantObjPrivs;
import static kr.co.bitnine.octopus.sql.OctopusSqlObjectPrivileges.OctopusSqlRevokeObjPrivs;
            sysPrivs.add(SystemPrivilege.GRANT_ANY_OBJECT_PRIVILEGE);
        }

        @Override
        public void exitSysPrivGrantAnyPriv(OctopusSqlParser.SysPrivGrantAnyPrivContext ctx) {
            assert sysPrivs != null;
            sysPrivs.add(SystemPrivilege.GRANT_ANY_PRIVILEGE);
        }

        @Override
        public void exitSysPrivAllPrivs(OctopusSqlParser.SysPrivAllPrivsContext ctx) {
            assert sysPrivs != null;
            sysPrivs.addAll(Arrays.asList(SystemPrivilege.values()));
        }

        @Override
        public void exitGrantObjectPrivileges(OctopusSqlParser.GrantObjectPrivilegesContext ctx) {
            assert this.objPrivs != null;

            List<ObjectPrivilege> objPrivsList = new ArrayList<>(this.objPrivs);

            String[] objName = {
                ctx.object().dataSourceName().getText(),
                ctx.object().schemaName().getText()
            };

            Set<String> grantees = new HashSet<>();
            for (OctopusSqlParser.GranteeContext grantee : ctx.grantees().grantee())
                grantees.add(grantee.getText());

// Path: octopus-core/src/main/java/kr/co/bitnine/octopus/sql/OctopusSqlObjectPrivileges.java
// static class OctopusSqlGrantObjPrivs extends OctopusSqlObjectPrivileges {
//     OctopusSqlGrantObjPrivs(List<ObjectPrivilege> objPrivs, String[] objName, List<String> grantees) {
//         super(objPrivs, objName, grantees);
//     }
// 
//     @Override
//     public Type getType() {
//         return Type.GRANT_OBJ_PRIVS;
//     }
// }
// 
// Path: octopus-core/src/main/java/kr/co/bitnine/octopus/sql/OctopusSqlObjectPrivileges.java
// static class OctopusSqlRevokeObjPrivs extends OctopusSqlObjectPrivileges {
//     OctopusSqlRevokeObjPrivs(List<ObjectPrivilege> objPrivs, String[] objName, List<String> revokees) {
//         super(objPrivs, objName, revokees);
//     }
// 
//     @Override
//     public Type getType() {
//         return Type.REVOKE_OBJ_PRIVS;
//     }
// }


// Path: octopus-core/src/main/java/kr/co/bitnine/octopus/sql/OctopusSql.java
import static kr.co.bitnine.octopus.sql.OctopusSqlSystemPrivileges.OctopusSqlGrantSysPrivs;
import static kr.co.bitnine.octopus.sql.OctopusSqlSystemPrivileges.OctopusSqlRevokeSysPrivs;
import kr.co.bitnine.octopus.meta.privilege.ObjectPrivilege;
import kr.co.bitnine.octopus.meta.privilege.SystemPrivilege;
import kr.co.bitnine.octopus.postgres.executor.TupleSet;
import org.antlr.v4.runtime.ANTLRInputStream;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.ParserRuleContext;
import org.antlr.v4.runtime.tree.ParseTreeWalker;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import static kr.co.bitnine.octopus.sql.OctopusSqlObjectPrivileges.OctopusSqlGrantObjPrivs;
import static kr.co.bitnine.octopus.sql.OctopusSqlObjectPrivileges.OctopusSqlRevokeObjPrivs;

            sysPrivs.add(SystemPrivilege.GRANT_ANY_OBJECT_PRIVILEGE);
        }

        @Override
        public void exitSysPrivGrantAnyPriv(OctopusSqlParser.SysPrivGrantAnyPrivContext ctx) {
            assert sysPrivs != null;
            sysPrivs.add(SystemPrivilege.GRANT_ANY_PRIVILEGE);
        }

        @Override
        public void exitSysPrivAllPrivs(OctopusSqlParser.SysPrivAllPrivsContext ctx) {
            assert sysPrivs != null;
            sysPrivs.addAll(Arrays.asList(SystemPrivilege.values()));
        }

        @Override
        public void exitGrantObjectPrivileges(OctopusSqlParser.GrantObjectPrivilegesContext ctx) {
            assert this.objPrivs != null;

            List<ObjectPrivilege> objPrivsList = new ArrayList<>(this.objPrivs);

            String[] objName = {
                ctx.object().dataSourceName().getText(),
                ctx.object().schemaName().getText()
            };

            Set<String> grantees = new HashSet<>();
            for (OctopusSqlParser.GranteeContext grantee : ctx.grantees().grantee())
                grantees.add(grantee.getText());

            commands.add(new OctopusSqlGrantObjPrivs(objPrivsList, objName, new ArrayList<>(grantees)));