content: /*
   * Copyright 1999-2012 Alibaba Group.
   *  
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *  
   *      http://www.apache.org/licenses/LICENSE-2.0
   *  
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  package com.alibaba.cobar.server.parser;
  
  import com.alibaba.cobar.parser.util.ParseUtil;
  
  /**
   * @author xianmao.hexm 2011-5-7 下午01:22:57
   */
  public final class ServerParseSet {
  
      public static final int OTHER = -1;
      public static final int AUTOCOMMIT_ON = 1;
      public static final int AUTOCOMMIT_OFF = 2;
      public static final int TX_READ_UNCOMMITTED = 3;
      public static final int TX_READ_COMMITTED = 4;
      public static final int TX_REPEATED_READ = 5;
      public static final int TX_SERIALIZABLE = 6;
      public static final int NAMES = 7;
      public static final int CHARACTER_SET_CLIENT = 8;
      public static final int CHARACTER_SET_CONNECTION = 9;
      public static final int CHARACTER_SET_RESULTS = 10;
  
      public static int parse(String stmt, int offset) {
          int i = offset;
          for (; i < stmt.length(); i++) {
              switch (stmt.charAt(i)) {
              case ' ':
              case '\r':
              case '\n':
              case '\t':
                  continue;
              case '/':
              case '#':
                  i = ParseUtil.comment(stmt, i);
                  continue;
              case 'A':
              case 'a':
                  return autocommit(stmt, i);
              case 'C':
              case 'c':
                  return characterSet(stmt, i, 0);
              case 'N':
              case 'n':
                  return names(stmt, i);
              case 'S':
              case 's':
                  return session(stmt, i);
              case 'T':
              case 't':
                  return transaction(stmt, i);
              default:
                  return OTHER;
              }
          }
          return OTHER;
      }
  
      // SET AUTOCOMMIT(' '=)
      private static int autocommit(String stmt, int offset) {
          if (stmt.length() > offset + 9) {
              char c1 = stmt.charAt(++offset);
              char c2 = stmt.charAt(++offset);
              char c3 = stmt.charAt(++offset);
              char c4 = stmt.charAt(++offset);
              char c5 = stmt.charAt(++offset);
              char c6 = stmt.charAt(++offset);
              char c7 = stmt.charAt(++offset);
              char c8 = stmt.charAt(++offset);
              char c9 = stmt.charAt(++offset);
              if ((c1 == 'U' || c1 == 'u') && (c2 == 'T' || c2 == 't') && (c3 == 'O' || c3 == 'o')
                      && (c4 == 'C' || c4 == 'c') && (c5 == 'O' || c5 == 'o') && (c6 == 'M' || c6 == 'm')
                      && (c7 == 'M' || c7 == 'm') && (c8 == 'I' || c8 == 'i') && (c9 == 'T' || c9 == 't')) {
                  while (stmt.length() > ++offset) {
                      switch (stmt.charAt(offset)) {
                      case ' ':
                      case '\r':
                      case '\n':
                      case '\t':
                          continue;
                      case '=':
                          return autocommitValue(stmt, offset);
                      default:
                          return OTHER;
                      }
                  }
              }
          }
          return OTHER;
      }
  
      private static int autocommitValue(String stmt, int offset) {
          for (;;) {
              offset++;
              if (stmt.length() <= offset) {
                  return OTHER;
              }
              switch (stmt.charAt(offset)) {
              case ' ':
              case '\r':
              case '\n':
              case '\t':
                  continue;
              case '1':
                  if (stmt.length() == ++offset || ParseUtil.isEOF(stmt.charAt(offset))) {
                      return AUTOCOMMIT_ON;
                  } else {
                      return OTHER;
                  }
              case '0':
                  if (stmt.length() == ++offset || ParseUtil.isEOF(stmt.charAt(offset))) {
                      return AUTOCOMMIT_OFF;
                  } else {
                      return OTHER;
                  }
              case 'O':
              case 'o':
                  return autocommitOn(stmt, offset);
              default:
                  return OTHER;
              }
          }
      }
  
      private static int autocommitOn(String stmt, int offset) {
          if (stmt.length() > ++offset) {
              switch (stmt.charAt(offset)) {
              case 'N':
              case 'n':
                  if (stmt.length() == ++offset || ParseUtil.isEOF(stmt.charAt(offset))) {
                      return AUTOCOMMIT_ON;
                  } else {
                      return OTHER;
                  }
              case 'F':
              case 'f':
                  return autocommitOff(stmt, offset);
              default:
                  return OTHER;
              }
          }
          return OTHER;
      }
  
      // SET AUTOCOMMIT = OFF
      private static int autocommitOff(String stmt, int offset) {
          if (stmt.length() > ++offset) {
              switch (stmt.charAt(offset)) {
              case 'F':
              case 'f':
                  if (stmt.length() == ++offset || ParseUtil.isEOF(stmt.charAt(offset))) {
                      return AUTOCOMMIT_OFF;
                  } else {
                      return OTHER;
                  }
              default:
                  return OTHER;
              }
          }
          return OTHER;
      }
  
      // SET NAMES' '
      private static int names(String stmt, int offset) {
          if (stmt.length() > offset + 5) {
              char c1 = stmt.charAt(++offset);
              char c2 = stmt.charAt(++offset);
              char c3 = stmt.charAt(++offset);
              char c4 = stmt.charAt(++offset);
              if ((c1 == 'A' || c1 == 'a') && (c2 == 'M' || c2 == 'm') && (c3 == 'E' || c3 == 'e')
                      && (c4 == 'S' || c4 == 's') && stmt.charAt(++offset) == ' ') {
                  return (offset << 8) | NAMES;
              }
          }
          return OTHER;
      }
  
      // SET CHARACTER_SET_
      private static int characterSet(String stmt, int offset, int depth) {
          if (stmt.length() > offset + 14) {
              char c1 = stmt.charAt(++offset);
              char c2 = stmt.charAt(++offset);
              char c3 = stmt.charAt(++offset);
              char c4 = stmt.charAt(++offset);
              char c5 = stmt.charAt(++offset);
              char c6 = stmt.charAt(++offset);
              char c7 = stmt.charAt(++offset);
              char c8 = stmt.charAt(++offset);
              char c9 = stmt.charAt(++offset);
              char c10 = stmt.charAt(++offset);
              char c11 = stmt.charAt(++offset);
              char c12 = stmt.charAt(++offset);
              char c13 = stmt.charAt(++offset);
              char c14 = stmt.charAt(++offset);
              if ((c1 == 'H' || c1 == 'h') && (c2 == 'A' || c2 == 'a') && (c3 == 'R' || c3 == 'r')
                      && (c4 == 'A' || c4 == 'a') && (c5 == 'C' || c5 == 'c') && (c6 == 'T' || c6 == 't')
                      && (c7 == 'E' || c7 == 'e') && (c8 == 'R' || c8 == 'r') && (c9 == '_')
                      && (c10 == 'S' || c10 == 's') && (c11 == 'E' || c11 == 'e') && (c12 == 'T' || c12 == 't')
                      && (c13 == '_')) {
                  switch (c14) {
                  case 'R':
                  case 'r':
                      return characterSetResults(stmt, offset);
                  case 'C':
                  case 'c':
                      return characterSetC(stmt, offset);
                  default:
                      return OTHER;
                  }
              }
          }
          return OTHER;
      }
  
      // SET CHARACTER_SET_RESULTS =
      private static int characterSetResults(String stmt, int offset) {
          if (stmt.length() > offset + 6) {
              char c1 = stmt.charAt(++offset);
              char c2 = stmt.charAt(++offset);
              char c3 = stmt.charAt(++offset);
              char c4 = stmt.charAt(++offset);
              char c5 = stmt.charAt(++offset);
              char c6 = stmt.charAt(++offset);
              if ((c1 == 'E' || c1 == 'e') && (c2 == 'S' || c2 == 's') && (c3 == 'U' || c3 == 'u')
                      && (c4 == 'L' || c4 == 'l') && (c5 == 'T' || c5 == 't') && (c6 == 'S' || c6 == 's')) {
                  while (stmt.length() > ++offset) {
                      switch (stmt.charAt(offset)) {
                      case ' ':
                      case '\r':
                      case '\n':
                      case '\t':
                          continue;
                      case '=':
                          while (stmt.length() > ++offset) {
                              switch (stmt.charAt(offset)) {
                              case ' ':
                              case '\r':
                              case '\n':
                              case '\t':
                                  continue;
                              default:
                                  return (offset << 8) | CHARACTER_SET_RESULTS;
                              }
                          }
                          return OTHER;
                      default:
                          return OTHER;
                      }
                  }
              }
          }
          return OTHER;
      }
  
      // SET CHARACTER_SET_C
      private static int characterSetC(String stmt, int offset) {
          if (stmt.length() > offset + 1) {
              char c1 = stmt.charAt(++offset);
              switch (c1) {
              case 'o':
              case 'O':
                  return characterSetConnection(stmt, offset);
              case 'l':
              case 'L':
                  return characterSetClient(stmt, offset);
              default:
                  return OTHER;
              }
          }
          return OTHER;
      }
  
      // SET CHARACTER_SET_CONNECTION =
      private static int characterSetConnection(String stmt, int offset) {
          if (stmt.length() > offset + 8) {
              char c1 = stmt.charAt(++offset);
              char c2 = stmt.charAt(++offset);
              char c3 = stmt.charAt(++offset);
              char c4 = stmt.charAt(++offset);
              char c5 = stmt.charAt(++offset);
              char c6 = stmt.charAt(++offset);
              char c7 = stmt.charAt(++offset);
              char c8 = stmt.charAt(++offset);
              if ((c1 == 'N' || c1 == 'n') && (c2 == 'N' || c2 == 'n') && (c3 == 'E' || c3 == 'e')
                      && (c4 == 'C' || c4 == 'c') && (c5 == 'T' || c5 == 't') && (c6 == 'I' || c6 == 'i')
                      && (c7 == 'O' || c7 == 'o') && (c8 == 'N' || c8 == 'n')) {
                  while (stmt.length() > ++offset) {
                      switch (stmt.charAt(offset)) {
                      case ' ':
                      case '\r':
                      case '\n':
                      case '\t':
                          continue;
                      case '=':
                          while (stmt.length() > ++offset) {
                              switch (stmt.charAt(offset)) {
                              case ' ':
                              case '\r':
                              case '\n':
                              case '\t':
                                  continue;
                              default:
                                  return (offset << 8) | CHARACTER_SET_CONNECTION;
                              }
                          }
                          return OTHER;
                      default:
                          return OTHER;
                      }
                  }
              }
          }
          return OTHER;
      }
  
      // SET CHARACTER_SET_CLIENT =
      private static int characterSetClient(String stmt, int offset) {
          if (stmt.length() > offset + 4) {
              char c1 = stmt.charAt(++offset);
              char c2 = stmt.charAt(++offset);
              char c3 = stmt.charAt(++offset);
              char c4 = stmt.charAt(++offset);
              if ((c1 == 'I' || c1 == 'i') && (c2 == 'E' || c2 == 'e') && (c3 == 'N' || c3 == 'n')
                      && (c4 == 'T' || c4 == 't')) {
                  while (stmt.length() > ++offset) {
                      switch (stmt.charAt(offset)) {
                      case ' ':
                      case '\r':
                      case '\n':
                      case '\t':
                          continue;
                      case '=':
                          while (stmt.length() > ++offset) {
                              switch (stmt.charAt(offset)) {
                              case ' ':
                              case '\r':
                              case '\n':
                              case '\t':
                                  continue;
                              default:
                                  return (offset << 8) | CHARACTER_SET_CLIENT;
                              }
                          }
                          return OTHER;
                      default:
                          return OTHER;
                      }
                  }
              }
          }
          return OTHER;
      }
  
      // SET SESSION' '
      private static int session(String stmt, int offset) {
          if (stmt.length() > offset + 7) {
              char c1 = stmt.charAt(++offset);
              char c2 = stmt.charAt(++offset);
              char c3 = stmt.charAt(++offset);
              char c4 = stmt.charAt(++offset);
              char c5 = stmt.charAt(++offset);
              char c6 = stmt.charAt(++offset);
              if ((c1 == 'E' || c1 == 'e') && (c2 == 'S' || c2 == 's') && (c3 == 'S' || c3 == 's')
                      && (c4 == 'I' || c4 == 'i') && (c5 == 'O' || c5 == 'o') && (c6 == 'N' || c6 == 'n')
                      && stmt.charAt(++offset) == ' ') {
                  for (;;) {
                      if (stmt.length() > ++offset) {
                          switch (stmt.charAt(offset)) {
                          case ' ':
                          case '\r':
                          case '\n':
                          case '\t':
                              continue;
                          case 'T':
                          case 't':
                              return transaction(stmt, offset);
                          default:
                              return OTHER;
                          }
                      }
                      return OTHER;
                  }
              }
          }
          return OTHER;
      }
  
      // SET [SESSION] TRANSACTION ISOLATION LEVEL
      private static int transaction(String stmt, int offset) {
          if (stmt.length() > offset + 11) {
              char c1 = stmt.charAt(++offset);
              char c2 = stmt.charAt(++offset);
              char c3 = stmt.charAt(++offset);
              char c4 = stmt.charAt(++offset);
              char c5 = stmt.charAt(++offset);
              char c6 = stmt.charAt(++offset);
              char c7 = stmt.charAt(++offset);
              char c8 = stmt.charAt(++offset);
              char c9 = stmt.charAt(++offset);
              char c10 = stmt.charAt(++offset);
              if ((c1 == 'R' || c1 == 'r') && (c2 == 'A' || c2 == 'a') && (c3 == 'N' || c3 == 'n')
                      && (c4 == 'S' || c4 == 's') && (c5 == 'A' || c5 == 'a') && (c6 == 'C' || c6 == 'c')
                      && (c7 == 'T' || c7 == 't') && (c8 == 'I' || c8 == 'i') && (c9 == 'O' || c9 == 'o')
                      && (c10 == 'N' || c10 == 'n') && stmt.charAt(++offset) == ' ') {
                  for (;;) {
                      if (stmt.length() > ++offset) {
                          switch (stmt.charAt(offset)) {
                          case ' ':
                          case '\r':
                          case '\n':
                          case '\t':
                              continue;
                          case 'I':
                          case 'i':
                              return isolation(stmt, offset);
                          default:
                              return OTHER;
                          }
                      }
                      return OTHER;
                  }
              }
          }
          return OTHER;
      }
  
      // SET [SESSION] TRANSACTION ISOLATION LEVEL
      private static int isolation(String stmt, int offset) {
          if (stmt.length() > offset + 9) {
              char c1 = stmt.charAt(++offset);
              char c2 = stmt.charAt(++offset);
              char c3 = stmt.charAt(++offset);
              char c4 = stmt.charAt(++offset);
              char c5 = stmt.charAt(++offset);
              char c6 = stmt.charAt(++offset);
              char c7 = stmt.charAt(++offset);
              char c8 = stmt.charAt(++offset);
              if ((c1 == 'S' || c1 == 's') && (c2 == 'O' || c2 == 'o') && (c3 == 'L' || c3 == 'l')
                      && (c4 == 'A' || c4 == 'a') && (c5 == 'T' || c5 == 't') && (c6 == 'I' || c6 == 'i')
                      && (c7 == 'O' || c7 == 'o') && (c8 == 'N' || c8 == 'n') && stmt.charAt(++offset) == ' ') {
                  for (;;) {
                      if (stmt.length() > ++offset) {
                          switch (stmt.charAt(offset)) {
                          case ' ':
                          case '\r':
                          case '\n':
                          case '\t':
                              continue;
                          case 'L':
                          case 'l':
                              return level(stmt, offset);
                          default:
                              return OTHER;
                          }
                      }
                      return OTHER;
                  }
              }
          }
          return OTHER;
      }
  
      // SET [SESSION] TRANSACTION ISOLATION LEVEL' '
      private static int level(String stmt, int offset) {
          if (stmt.length() > offset + 5) {
              char c1 = stmt.charAt(++offset);
              char c2 = stmt.charAt(++offset);
              char c3 = stmt.charAt(++offset);
              char c4 = stmt.charAt(++offset);
              if ((c1 == 'E' || c1 == 'e') && (c2 == 'V' || c2 == 'v') && (c3 == 'E' || c3 == 'e')
                      && (c4 == 'L' || c4 == 'l') && stmt.charAt(++offset) == ' ') {
                  for (;;) {
                      if (stmt.length() > ++offset) {
                          switch (stmt.charAt(offset)) {
                          case ' ':
                          case '\r':
                          case '\n':
                          case '\t':
                              continue;
                          case 'R':
                          case 'r':
                              return rCheck(stmt, offset);
                          case 'S':
                          case 's':
                              return serializable(stmt, offset);
                          default:
                              return OTHER;
                          }
                      }
                      return OTHER;
                  }
              }
          }
          return OTHER;
      }
  
      // SET [SESSION] TRANSACTION ISOLATION LEVEL SERIALIZABLE
      private static int serializable(String stmt, int offset) {
          if (stmt.length() > offset + 11) {
              char c1 = stmt.charAt(++offset);
              char c2 = stmt.charAt(++offset);
              char c3 = stmt.charAt(++offset);
              char c4 = stmt.charAt(++offset);
              char c5 = stmt.charAt(++offset);
              char c6 = stmt.charAt(++offset);
              char c7 = stmt.charAt(++offset);
              char c8 = stmt.charAt(++offset);
              char c9 = stmt.charAt(++offset);
              char c10 = stmt.charAt(++offset);
              char c11 = stmt.charAt(++offset);
              if ((c1 == 'E' || c1 == 'e') && (c2 == 'R' || c2 == 'r') && (c3 == 'I' || c3 == 'i')
                      && (c4 == 'A' || c4 == 'a') && (c5 == 'L' || c5 == 'l') && (c6 == 'I' || c6 == 'i')
                      && (c7 == 'Z' || c7 == 'z') && (c8 == 'A' || c8 == 'a') && (c9 == 'B' || c9 == 'b')
                      && (c10 == 'L' || c10 == 'l') && (c11 == 'E' || c11 == 'e')
                      && (stmt.length() == ++offset || ParseUtil.isEOF(stmt.charAt(offset)))) {
                  return TX_SERIALIZABLE;
              }
          }
          return OTHER;
      }
  
      // READ' '|REPEATABLE
      private static int rCheck(String stmt, int offset) {
          if (stmt.length() > ++offset) {
              switch (stmt.charAt(offset)) {
              case 'E':
              case 'e':
                  return eCheck(stmt, offset);
              default:
                  return OTHER;
              }
          }
          return OTHER;
      }
  
      // READ' '|REPEATABLE
      private static int eCheck(String stmt, int offset) {
          if (stmt.length() > ++offset) {
              switch (stmt.charAt(offset)) {
              case 'A':
              case 'a':
                  return aCheck(stmt, offset);
              case 'P':
              case 'p':
                  return pCheck(stmt, offset);
              default:
                  return OTHER;
              }
          }
          return OTHER;
      }
  
      // READ' '
      private static int aCheck(String stmt, int offset) {
          if (stmt.length() > offset + 2) {
              char c1 = stmt.charAt(++offset);
              if ((c1 == 'D' || c1 == 'd') && stmt.charAt(++offset) == ' ') {
                  for (;;) {
                      if (stmt.length() > ++offset) {
                          switch (stmt.charAt(offset)) {
                          case ' ':
                          case '\r':
                          case '\n':
                          case '\t':
                              continue;
                          case 'C':
                          case 'c':
                              return committed(stmt, offset);
                          case 'U':
                          case 'u':
                              return uncommitted(stmt, offset);
                          default:
                              return OTHER;
                          }
                      }
                      return OTHER;
                  }
              }
          }
          return OTHER;
      }
  
      // COMMITTED
      private static int committed(String stmt, int offset) {
          if (stmt.length() > offset + 8) {
              char c1 = stmt.charAt(++offset);
              char c2 = stmt.charAt(++offset);
              char c3 = stmt.charAt(++offset);
              char c4 = stmt.charAt(++offset);
              char c5 = stmt.charAt(++offset);
              char c6 = stmt.charAt(++offset);
              char c7 = stmt.charAt(++offset);
              char c8 = stmt.charAt(++offset);
              if ((c1 == 'O' || c1 == 'o') && (c2 == 'M' || c2 == 'm') && (c3 == 'M' || c3 == 'm')
                      && (c4 == 'I' || c4 == 'i') && (c5 == 'T' || c5 == 't') && (c6 == 'T' || c6 == 't')
                      && (c7 == 'E' || c7 == 'e') && (c8 == 'D' || c8 == 'd')
                      && (stmt.length() == ++offset || ParseUtil.isEOF(stmt.charAt(offset)))) {
                  return TX_READ_COMMITTED;
              }
          }
          return OTHER;
      }
  
      // UNCOMMITTED
      private static int uncommitted(String stmt, int offset) {
          if (stmt.length() > offset + 10) {
              char c1 = stmt.charAt(++offset);
              char c2 = stmt.charAt(++offset);
              char c3 = stmt.charAt(++offset);
              char c4 = stmt.charAt(++offset);
              char c5 = stmt.charAt(++offset);
              char c6 = stmt.charAt(++offset);
              char c7 = stmt.charAt(++offset);
              char c8 = stmt.charAt(++offset);
              char c9 = stmt.charAt(++offset);
              char c10 = stmt.charAt(++offset);
              if ((c1 == 'N' || c1 == 'n') && (c2 == 'C' || c2 == 'c') && (c3 == 'O' || c3 == 'o')
                      && (c4 == 'M' || c4 == 'm') && (c5 == 'M' || c5 == 'm') && (c6 == 'I' || c6 == 'i')
                      && (c7 == 'T' || c7 == 't') && (c8 == 'T' || c8 == 't') && (c9 == 'E' || c9 == 'e')
                      && (c10 == 'D' || c10 == 'd')
                      && (stmt.length() == ++offset || ParseUtil.isEOF(stmt.charAt(offset)))) {
                  return TX_READ_UNCOMMITTED;
              }
          }
          return OTHER;
      }
  
      // REPEATABLE
      private static int pCheck(String stmt, int offset) {
          if (stmt.length() > offset + 8) {
              char c1 = stmt.charAt(++offset);
              char c2 = stmt.charAt(++offset);
              char c3 = stmt.charAt(++offset);
              char c4 = stmt.charAt(++offset);
              char c5 = stmt.charAt(++offset);
              char c6 = stmt.charAt(++offset);
              char c7 = stmt.charAt(++offset);
              if ((c1 == 'E' || c1 == 'e') && (c2 == 'A' || c2 == 'a') && (c3 == 'T' || c3 == 't')
                      && (c4 == 'A' || c4 == 'a') && (c5 == 'B' || c5 == 'b') && (c6 == 'L' || c6 == 'l')
                      && (c7 == 'E' || c7 == 'e') && stmt.charAt(++offset) == ' ') {
                  for (;;) {
                      if (stmt.length() > ++offset) {
                          switch (stmt.charAt(offset)) {
                          case ' ':
                          case '\r':
                          case '\n':
                          case '\t':
                              continue;
                          case 'R':
                          case 'r':
                              return prCheck(stmt, offset);
                          default:
                              return OTHER;
                          }
                      }
                      return OTHER;
                  }
              }
          }
          return OTHER;
      }
  
      // READ
      private static int prCheck(String stmt, int offset) {
          if (stmt.length() > offset + 3) {
              char c1 = stmt.charAt(++offset);
              char c2 = stmt.charAt(++offset);
              char c3 = stmt.charAt(++offset);
              if ((c1 == 'E' || c1 == 'e') && (c2 == 'A' || c2 == 'a') && (c3 == 'D' || c3 == 'd')
                      && (stmt.length() == ++offset || ParseUtil.isEOF(stmt.charAt(offset)))) {
                  return TX_REPEATED_READ;
              }
          }
          return OTHER;
      }
  
  }
  