Ejemplo n.º 1
0
 @SuppressWarnings("rawtypes")
 public void checkListResolve(Collection array) {
   if (resolveStatus == NeedToResolve) {
     if (array instanceof List) {
       final int index = array.size() - 1;
       final List list = (List) array;
       ResolveTask task = getLastResolveTask();
       task.fieldDeserializer = new ResolveFieldDeserializer(this, list, index);
       task.ownerContext = context;
       setResolveStatus(DefaultJSONParser.NONE);
     } else {
       ResolveTask task = getLastResolveTask();
       task.fieldDeserializer = new ResolveFieldDeserializer(array);
       task.ownerContext = context;
       setResolveStatus(DefaultJSONParser.NONE);
     }
   }
 }
Ejemplo n.º 2
0
 @SuppressWarnings("rawtypes")
 public void checkMapResolve(Map object, Object fieldName) {
   if (resolveStatus == NeedToResolve) {
     ResolveFieldDeserializer fieldResolver = new ResolveFieldDeserializer(object, fieldName);
     ResolveTask task = getLastResolveTask();
     task.fieldDeserializer = fieldResolver;
     task.ownerContext = context;
     setResolveStatus(DefaultJSONParser.NONE);
   }
 }
Ejemplo n.º 3
0
 @SuppressWarnings("rawtypes")
 public void checkMapResolve(Map object, String fieldName) {
   if (resolveStatus == NeedToResolve) {
     MapResolveFieldDeserializer fieldResolver =
         new MapResolveFieldDeserializer(object, fieldName);
     ResolveTask task = getLastResolveTask();
     task.setFieldDeserializer(fieldResolver);
     task.setOwnerContext(context);
     setResolveStatus(DefaultJSONParser.NONE);
   }
 }
Ejemplo n.º 4
0
 @SuppressWarnings("rawtypes")
 public void checkListResolve(Collection array) {
   if (resolveStatus == NeedToResolve) {
     final int index = array.size() - 1;
     final List list = (List) array;
     ResolveTask task = getLastResolveTask();
     task.setFieldDeserializer(new ListResolveFieldDeserializer(this, list, index));
     task.setOwnerContext(context);
     setResolveStatus(DefaultJSONParser.NONE);
   }
 }
Ejemplo n.º 5
0
  @SuppressWarnings({"unchecked", "rawtypes"})
  public final Object parseObject(final Map object, Object fieldName) {
    final JSONLexer lexer = this.lexer;

    if (lexer.token() != JSONToken.LBRACE && lexer.token() != JSONToken.COMMA) {
      throw new JSONException("syntax error, expect {, actual " + lexer.tokenName());
    }

    ParseContext context = this.getContext();
    try {
      boolean setContextFlag = false;
      for (; ; ) {
        lexer.skipWhitespace();
        char ch = lexer.getCurrent();
        if (isEnabled(Feature.AllowArbitraryCommas)) {
          while (ch == ',') {
            lexer.next();
            lexer.skipWhitespace();
            ch = lexer.getCurrent();
          }
        }

        boolean isObjectKey = false;
        Object key;
        if (ch == '"') {
          key = lexer.scanSymbol(symbolTable, '"');
          lexer.skipWhitespace();
          ch = lexer.getCurrent();
          if (ch != ':') {
            throw new JSONException("expect ':' at " + lexer.pos() + ", name " + key);
          }
        } else if (ch == '}') {
          lexer.next();
          lexer.resetStringPosition();
          lexer.nextToken();
          return object;
        } else if (ch == '\'') {
          if (!isEnabled(Feature.AllowSingleQuotes)) {
            throw new JSONException("syntax error");
          }

          key = lexer.scanSymbol(symbolTable, '\'');
          lexer.skipWhitespace();
          ch = lexer.getCurrent();
          if (ch != ':') {
            throw new JSONException("expect ':' at " + lexer.pos());
          }
        } else if (ch == EOI) {
          throw new JSONException("syntax error");
        } else if (ch == ',') {
          throw new JSONException("syntax error");
        } else if ((ch >= '0' && ch <= '9') || ch == '-') {
          lexer.resetStringPosition();
          lexer.scanNumber();
          if (lexer.token() == JSONToken.LITERAL_INT) {
            key = lexer.integerValue();
          } else {
            key = lexer.decimalValue(true);
          }
          ch = lexer.getCurrent();
          if (ch != ':') {
            throw new JSONException("expect ':' at " + lexer.pos() + ", name " + key);
          }
        } else if (ch == '{' || ch == '[') {
          lexer.nextToken();
          key = parse();
          isObjectKey = true;
        } else {
          if (!isEnabled(Feature.AllowUnQuotedFieldNames)) {
            throw new JSONException("syntax error");
          }

          key = lexer.scanSymbolUnQuoted(symbolTable);
          lexer.skipWhitespace();
          ch = lexer.getCurrent();
          if (ch != ':') {
            throw new JSONException("expect ':' at " + lexer.pos() + ", actual " + ch);
          }
        }

        if (!isObjectKey) {
          lexer.next();
          lexer.skipWhitespace();
        }

        ch = lexer.getCurrent();

        lexer.resetStringPosition();

        if (key == JSON.DEFAULT_TYPE_KEY) {
          String typeName = lexer.scanSymbol(symbolTable, '"');
          Class<?> clazz = TypeUtils.loadClass(typeName);

          if (clazz == null) {
            object.put(JSON.DEFAULT_TYPE_KEY, typeName);
            continue;
          }

          lexer.nextToken(JSONToken.COMMA);
          if (lexer.token() == JSONToken.RBRACE) {
            lexer.nextToken(JSONToken.COMMA);
            try {
              Object instance = null;
              ObjectDeserializer deserializer = this.config.getDeserializer(clazz);
              if (deserializer instanceof JavaBeanDeserializer) {
                instance = ((JavaBeanDeserializer) deserializer).createInstance(this, clazz);
              }

              if (instance == null) {
                if (clazz == Cloneable.class) {
                  instance = new HashMap();
                } else {
                  instance = clazz.newInstance();
                }
              }

              return instance;
            } catch (Exception e) {
              throw new JSONException("create instance error", e);
            }
          }

          this.setResolveStatus(TypeNameRedirect);

          if (this.context != null && !(fieldName instanceof Integer)) {
            this.popContext();
          }

          ObjectDeserializer deserializer = config.getDeserializer(clazz);
          return deserializer.deserialze(this, clazz, fieldName);
        }

        if (key == "$ref") {
          lexer.nextToken(JSONToken.LITERAL_STRING);
          if (lexer.token() == JSONToken.LITERAL_STRING) {
            String ref = lexer.stringVal();
            lexer.nextToken(JSONToken.RBRACE);

            Object refValue = null;
            if ("@".equals(ref)) {
              if (this.getContext() != null) {
                refValue = this.getContext().getObject();
              }
            } else if ("..".equals(ref)) {
              ParseContext parentContext = context.getParentContext();
              if (parentContext.getObject() != null) {
                refValue = parentContext.getObject();
              } else {
                addResolveTask(new ResolveTask(parentContext, ref));
                setResolveStatus(DefaultJSONParser.NeedToResolve);
              }
            } else if ("$".equals(ref)) {
              ParseContext rootContext = context;
              while (rootContext.getParentContext() != null) {
                rootContext = rootContext.getParentContext();
              }

              if (rootContext.getObject() != null) {
                refValue = rootContext.getObject();
              } else {
                addResolveTask(new ResolveTask(rootContext, ref));
                setResolveStatus(DefaultJSONParser.NeedToResolve);
              }
            } else {
              addResolveTask(new ResolveTask(context, ref));
              setResolveStatus(DefaultJSONParser.NeedToResolve);
            }

            if (lexer.token() != JSONToken.RBRACE) {
              throw new JSONException("syntax error");
            }
            lexer.nextToken(JSONToken.COMMA);

            return refValue;
          } else {
            throw new JSONException("illegal ref, " + JSONToken.name(lexer.token()));
          }
        }

        if (!setContextFlag) {
          setContext(object, fieldName);
          setContextFlag = true;

          // fix Issue #40
          if (this.context != null && !(fieldName instanceof Integer)) {
            this.popContext();
          }
        }

        Object value;
        if (ch == '"') {
          lexer.scanString();
          String strValue = lexer.stringVal();
          value = strValue;

          if (lexer.isEnabled(Feature.AllowISO8601DateFormat)) {
            JSONScanner iso8601Lexer = new JSONScanner(strValue);
            if (iso8601Lexer.scanISO8601DateIfMatch()) {
              value = iso8601Lexer.getCalendar().getTime();
            }
            iso8601Lexer.close();
          }

          if (object.getClass() == JSONObject.class) {
            object.put(key.toString(), value);
          } else {
            object.put(key, value);
          }
        } else if (ch >= '0' && ch <= '9' || ch == '-') {
          lexer.scanNumber();
          if (lexer.token() == JSONToken.LITERAL_INT) {
            value = lexer.integerValue();
          } else {
            value = lexer.numberValue();
          }

          object.put(key, value);
        } else if (ch == '[') { // 减少嵌套,兼容android
          lexer.nextToken();
          JSONArray list = new JSONArray();
          this.parseArray(list, key);
          value = list;
          object.put(key, value);

          if (lexer.token() == JSONToken.RBRACE) {
            lexer.nextToken();
            return object;
          } else if (lexer.token() == JSONToken.COMMA) {
            continue;
          } else {
            throw new JSONException("syntax error");
          }
        } else if (ch == '{') { // 减少嵌套,兼容android
          lexer.nextToken();
          Object obj = this.parseObject(new JSONObject(), key);
          checkMapResolve(object, key.toString());

          if (object.getClass() == JSONObject.class) {
            object.put(key.toString(), obj);
          } else {
            object.put(key, obj);
          }

          setContext(context, obj, key);

          if (lexer.token() == JSONToken.RBRACE) {
            lexer.nextToken();

            setContext(context);
            return object;
          } else if (lexer.token() == JSONToken.COMMA) {
            continue;
          } else {
            throw new JSONException("syntax error, " + lexer.tokenName());
          }
        } else {
          lexer.nextToken();
          value = parse();
          object.put(key, value);

          if (lexer.token() == JSONToken.RBRACE) {
            lexer.nextToken();
            return object;
          } else if (lexer.token() == JSONToken.COMMA) {
            continue;
          } else {
            throw new JSONException("syntax error, position at " + lexer.pos() + ", name " + key);
          }
        }

        lexer.skipWhitespace();
        ch = lexer.getCurrent();
        if (ch == ',') {
          lexer.next();
          continue;
        } else if (ch == '}') {
          lexer.next();
          lexer.resetStringPosition();
          lexer.nextToken();

          this.setContext(object, fieldName);

          return object;
        } else {
          throw new JSONException("syntax error, position at " + lexer.pos() + ", name " + key);
        }
      }
    } finally {
      this.setContext(context);
    }
  }
Ejemplo n.º 6
0
  @SuppressWarnings("rawtypes")
  public static Map parseMap(
      DefaultJSONParser parser, Map<String, Object> map, Type valueType, Object fieldName) {
    JSONLexer lexer = parser.getLexer();

    if (lexer.token() != JSONToken.LBRACE) {
      throw new JSONException("syntax error, expect {, actual " + lexer.token());
    }

    ParseContext context = parser.getContext();
    try {
      for (; ; ) {
        lexer.skipWhitespace();
        char ch = lexer.getCurrent();
        if (parser.isEnabled(Feature.AllowArbitraryCommas)) {
          while (ch == ',') {
            lexer.next();
            lexer.skipWhitespace();
            ch = lexer.getCurrent();
          }
        }

        String key;
        if (ch == '"') {
          key = lexer.scanSymbol(parser.getSymbolTable(), '"');
          lexer.skipWhitespace();
          ch = lexer.getCurrent();
          if (ch != ':') {
            throw new JSONException("expect ':' at " + lexer.pos());
          }
        } else if (ch == '}') {
          lexer.next();
          lexer.resetStringPosition();
          lexer.nextToken(JSONToken.COMMA);
          return map;
        } else if (ch == '\'') {
          if (!parser.isEnabled(Feature.AllowSingleQuotes)) {
            throw new JSONException("syntax error");
          }

          key = lexer.scanSymbol(parser.getSymbolTable(), '\'');
          lexer.skipWhitespace();
          ch = lexer.getCurrent();
          if (ch != ':') {
            throw new JSONException("expect ':' at " + lexer.pos());
          }
        } else {
          if (!parser.isEnabled(Feature.AllowUnQuotedFieldNames)) {
            throw new JSONException("syntax error");
          }

          key = lexer.scanSymbolUnQuoted(parser.getSymbolTable());
          lexer.skipWhitespace();
          ch = lexer.getCurrent();
          if (ch != ':') {
            throw new JSONException("expect ':' at " + lexer.pos() + ", actual " + ch);
          }
        }

        lexer.next();
        lexer.skipWhitespace();
        ch = lexer.getCurrent();

        lexer.resetStringPosition();

        if (key == JSON.DEFAULT_TYPE_KEY) {
          String typeName = lexer.scanSymbol(parser.getSymbolTable(), '"');
          Class<?> clazz = TypeUtils.loadClass(typeName);

          if (clazz == map.getClass()) {
            lexer.nextToken(JSONToken.COMMA);
            if (lexer.token() == JSONToken.RBRACE) {
              lexer.nextToken(JSONToken.COMMA);
              return map;
            }
            continue;
          }

          ObjectDeserializer deserializer = parser.getConfig().getDeserializer(clazz);

          lexer.nextToken(JSONToken.COMMA);

          parser.setResolveStatus(DefaultJSONParser.TypeNameRedirect);

          if (context != null && !(fieldName instanceof Integer)) {
            parser.popContext();
          }

          return (Map) deserializer.deserialze(parser, clazz, fieldName);
        }

        Object value;
        lexer.nextToken();

        if (lexer.token() == JSONToken.NULL) {
          value = null;
          lexer.nextToken();
        } else {
          value = parser.parseObject(valueType);
        }

        map.put(key, value);
        parser.checkMapResolve(map, key);

        parser.setContext(context, value, key);

        final int tok = lexer.token();
        if (tok == JSONToken.EOF || tok == JSONToken.RBRACKET) {
          return map;
        }

        if (tok == JSONToken.RBRACE) {
          lexer.nextToken();
          return map;
        }
      }
    } finally {
      parser.setContext(context);
    }
  }
Ejemplo n.º 7
0
  public static Object parseMap(
      DefaultJSONParser parser,
      Map<Object, Object> map,
      Type keyType,
      Type valueType,
      Object fieldName) {
    JSONLexer lexer = parser.getLexer();

    if (lexer.token() != JSONToken.LBRACE && lexer.token() != JSONToken.COMMA) {
      throw new JSONException("syntax error, expect {, actual " + lexer.tokenName());
    }

    ObjectDeserializer keyDeserializer = parser.getConfig().getDeserializer(keyType);
    ObjectDeserializer valueDeserializer = parser.getConfig().getDeserializer(valueType);
    lexer.nextToken(keyDeserializer.getFastMatchToken());

    ParseContext context = parser.getContext();
    try {
      for (; ; ) {
        if (lexer.token() == JSONToken.RBRACE) {
          lexer.nextToken(JSONToken.COMMA);
          break;
        }

        if (lexer.token() == JSONToken.LITERAL_STRING && lexer.isRef()) {
          Object object = null;

          lexer.nextTokenWithColon(JSONToken.LITERAL_STRING);
          if (lexer.token() == JSONToken.LITERAL_STRING) {
            String ref = lexer.stringVal();
            if ("..".equals(ref)) {
              ParseContext parentContext = context.getParentContext();
              object = parentContext.getObject();
            } else if ("$".equals(ref)) {
              ParseContext rootContext = context;
              while (rootContext.getParentContext() != null) {
                rootContext = rootContext.getParentContext();
              }

              object = rootContext.getObject();
            } else {
              parser.addResolveTask(new ResolveTask(context, ref));
              parser.setResolveStatus(DefaultJSONParser.NeedToResolve);
            }
          } else {
            throw new JSONException("illegal ref, " + JSONToken.name(lexer.token()));
          }

          lexer.nextToken(JSONToken.RBRACE);
          if (lexer.token() != JSONToken.RBRACE) {
            throw new JSONException("illegal ref");
          }
          lexer.nextToken(JSONToken.COMMA);

          // parser.setContext(context, map, fieldName);
          // parser.setContext(context);

          return object;
        }

        if (map.size() == 0 //
            && lexer.token() == JSONToken.LITERAL_STRING //
            && JSON.DEFAULT_TYPE_KEY.equals(lexer.stringVal())) {
          lexer.nextTokenWithColon(JSONToken.LITERAL_STRING);
          lexer.nextToken(JSONToken.COMMA);
          if (lexer.token() == JSONToken.RBRACE) {
            lexer.nextToken();
            return map;
          }
          lexer.nextToken(keyDeserializer.getFastMatchToken());
        }

        Object key = keyDeserializer.deserialze(parser, keyType, null);

        if (lexer.token() != JSONToken.COLON) {
          throw new JSONException("syntax error, expect :, actual " + lexer.token());
        }

        lexer.nextToken(valueDeserializer.getFastMatchToken());

        Object value = valueDeserializer.deserialze(parser, valueType, key);

        map.put(key, value);

        if (lexer.token() == JSONToken.COMMA) {
          lexer.nextToken(keyDeserializer.getFastMatchToken());
        }
      }
    } finally {
      parser.setContext(context);
    }

    return map;
  }
Ejemplo n.º 8
0
  public Object deserialze(DefaultJSONParser parser, Type type, Object fieldName) {
    JSONLexerBase lexer = (JSONLexerBase) parser.getLexer();

    if (lexer.isEnabled(Feature.SortFeidFastMatch)) {
      return super.deserialze(parser, type, fieldName);
    }

    if (isSupportArrayToBean(lexer)) {
      // deserialzeArrayMapping
    }

    if (lexer.scanType("Department") == JSONLexerBase.NOT_MATCH) {
      return super.deserialze(parser, type, fieldName);
    }

    ParseContext mark_context = parser.getContext();
    int matchedCount = 0;
    Department instance = new Department();

    ParseContext context = parser.getContext();
    ParseContext childContext = parser.setContext(context, instance, fieldName);

    if (lexer.matchStat == JSONLexerBase.END) {
      return instance;
    }

    int matchStat = 0;
    int _asm_flag_0 = 0;
    int id_gen = 0;
    com.alibaba.json.test.codegen.Employee leader_gen = null;
    java.util.List members_gen = null;
    String name_gen;
    if (lexer.isEnabled(Feature.InitStringFieldAsEmpty)) {
      name_gen = lexer.stringDefaultValue();
      _asm_flag_0 |= 8;
    } else {
      name_gen = null;
    }
    boolean root_gen = false;
    com.alibaba.json.test.codegen.DepartmentType type_gen = null;
    boolean endFlag = false, restFlag = false;

    if ((!endFlag) && (!restFlag)) {
      id_gen = lexer.scanFieldInt(id_gen_prefix__);
      if (lexer.matchStat > 0) {
        _asm_flag_0 |= 1;
        matchedCount++;
      }
      if (lexer.matchStat == JSONLexerBase.NOT_MATCH) {
        restFlag = true;
      }
      if (lexer.matchStat == JSONLexerBase.END) {
        endFlag = true;
      }
    }
    if ((!endFlag) && (!restFlag)) {
      if (lexer.matchField(leader_gen_prefix__)) {
        _asm_flag_0 |= 2;
        matchedCount++;
        if (parser.getResolveStatus() == DefaultJSONParser.NeedToResolve) {
          ResolveTask resolveTask = parser.getLastResolveTask();
          resolveTask.ownerContext = parser.getContext();
          resolveTask.fieldDeserializer = this.getFieldDeserializer("leader");
          parser.setResolveStatus(DefaultJSONParser.NONE);
        }
      }
      if (lexer.matchStat > 0) {
        _asm_flag_0 |= 2;
        matchedCount++;
      }
      if (lexer.matchStat == JSONLexerBase.NOT_MATCH) {
        restFlag = true;
      }
      if (lexer.matchStat == JSONLexerBase.END) {
        endFlag = true;
      }
    }
    if ((!endFlag) && (!restFlag)) {
      if (lexer.matchField(members_gen_prefix__)) {
        _asm_flag_0 |= 4;
        if (lexer.token() == JSONToken.NULL) {
          lexer.nextToken(JSONToken.COMMA);
        } else {
          if (lexer.token() == JSONToken.LBRACKET) {
            if (members_gen_list_item_deser__ == null) {
              members_gen_list_item_deser__ =
                  parser.getConfig().getDeserializer(com.alibaba.json.test.codegen.Employee.class);
            }
            final int fastMatchToken = members_gen_list_item_deser__.getFastMatchToken();
            lexer.nextToken(fastMatchToken);
            members_gen = new java.util.ArrayList();
            ParseContext listContext = parser.getContext();
            parser.setContext(members_gen, "members");

            for (int i = 0; ; ++i) {
              if (lexer.token() == JSONToken.RBRACKET) {
                break;
              }
              com.alibaba.json.test.codegen.Employee itemValue =
                  members_gen_list_item_deser__.deserialze(parser, members_gen_list_item_type__, i);
              members_gen.add(itemValue);
              parser.checkListResolve(members_gen);
              if (lexer.token() == JSONToken.COMMA) {
                lexer.nextToken(fastMatchToken);
              }
            }
            parser.setContext(listContext);
            if (lexer.token() != JSONToken.RBRACKET) {
              restFlag = true;
            }
            lexer.nextToken(JSONToken.COMMA);

          } else {
            restFlag = true;
          }
        }
      }
      if (lexer.matchStat > 0) {
        _asm_flag_0 |= 4;
        matchedCount++;
      }
      if (lexer.matchStat == JSONLexerBase.NOT_MATCH) {
        restFlag = true;
      }
      if (lexer.matchStat == JSONLexerBase.END) {
        endFlag = true;
      }
    }
    if ((!endFlag) && (!restFlag)) {
      name_gen = lexer.scanFieldString(name_gen_prefix__);
      if (lexer.matchStat > 0) {
        _asm_flag_0 |= 8;
        matchedCount++;
      }
      if (lexer.matchStat == JSONLexerBase.NOT_MATCH) {
        restFlag = true;
      }
      if (lexer.matchStat == JSONLexerBase.END) {
        endFlag = true;
      }
    }
    if ((!endFlag) && (!restFlag)) {
      root_gen = lexer.scanFieldBoolean(root_gen_prefix__);
      if (lexer.matchStat > 0) {
        _asm_flag_0 |= 16;
        matchedCount++;
      }
      if (lexer.matchStat == JSONLexerBase.NOT_MATCH) {
        restFlag = true;
      }
      if (lexer.matchStat == JSONLexerBase.END) {
        endFlag = true;
      }
    }
    if ((!endFlag) && (!restFlag)) {
      String type_gen_enum_name = lexer.scanFieldSymbol(type_gen_prefix__, parser.getSymbolTable());
      if (type_gen_enum_name == null) {
        type_gen = com.alibaba.json.test.codegen.DepartmentType.valueOf(type_gen_enum_name);
      }
      if (lexer.matchStat > 0) {
        _asm_flag_0 |= 32;
        matchedCount++;
      }
      if (lexer.matchStat == JSONLexerBase.NOT_MATCH) {
        restFlag = true;
      }
      if (lexer.matchStat != JSONLexerBase.END) {
        restFlag = true;
      }
    }

    if (restFlag) {
      return super.parseRest(parser, type, fieldName, instance);
    }

    return instance;
  }
Ejemplo n.º 9
0
  @SuppressWarnings({"unchecked", "rawtypes"})
  public final Object parseObject(final Map object, Object fieldName) {
    final JSONLexer lexer = this.lexer;

    if (lexer.token() == JSONToken.NULL) {
      lexer.nextToken();
      return null;
    }

    if (lexer.token() == JSONToken.RBRACE) {
      lexer.nextToken();
      return object;
    }

    if (lexer.token() != JSONToken.LBRACE && lexer.token() != JSONToken.COMMA) {
      throw new JSONException(
          "syntax error, expect {, actual " + lexer.tokenName() + ", " + lexer.info());
    }

    ParseContext context = this.context;
    try {
      boolean setContextFlag = false;
      for (; ; ) {
        lexer.skipWhitespace();
        char ch = lexer.getCurrent();
        if (lexer.isEnabled(Feature.AllowArbitraryCommas)) {
          while (ch == ',') {
            lexer.next();
            lexer.skipWhitespace();
            ch = lexer.getCurrent();
          }
        }

        boolean isObjectKey = false;
        Object key;
        if (ch == '"') {
          key = lexer.scanSymbol(symbolTable, '"');
          lexer.skipWhitespace();
          ch = lexer.getCurrent();
          if (ch != ':') {
            throw new JSONException("expect ':' at " + lexer.pos() + ", name " + key);
          }
        } else if (ch == '}') {
          lexer.next();
          lexer.resetStringPosition();
          lexer.nextToken();
          return object;
        } else if (ch == '\'') {
          if (!lexer.isEnabled(Feature.AllowSingleQuotes)) {
            throw new JSONException("syntax error");
          }

          key = lexer.scanSymbol(symbolTable, '\'');
          lexer.skipWhitespace();
          ch = lexer.getCurrent();
          if (ch != ':') {
            throw new JSONException("expect ':' at " + lexer.pos());
          }
        } else if (ch == EOI) {
          throw new JSONException("syntax error");
        } else if (ch == ',') {
          throw new JSONException("syntax error");
        } else if ((ch >= '0' && ch <= '9') || ch == '-') {
          lexer.resetStringPosition();
          lexer.scanNumber();
          try {
            if (lexer.token() == JSONToken.LITERAL_INT) {
              key = lexer.integerValue();
            } else {
              key = lexer.decimalValue(true);
            }
          } catch (NumberFormatException e) {
            throw new JSONException("parse number key error" + lexer.info());
          }
          ch = lexer.getCurrent();
          if (ch != ':') {
            throw new JSONException("parse number key error" + lexer.info());
          }
        } else if (ch == '{' || ch == '[') {
          lexer.nextToken();
          key = parse();
          isObjectKey = true;
        } else {
          if (!lexer.isEnabled(Feature.AllowUnQuotedFieldNames)) {
            throw new JSONException("syntax error");
          }

          key = lexer.scanSymbolUnQuoted(symbolTable);
          lexer.skipWhitespace();
          ch = lexer.getCurrent();
          if (ch != ':') {
            throw new JSONException("expect ':' at " + lexer.pos() + ", actual " + ch);
          }
        }

        if (!isObjectKey) {
          lexer.next();
          lexer.skipWhitespace();
        }

        ch = lexer.getCurrent();

        lexer.resetStringPosition();

        if (key == JSON.DEFAULT_TYPE_KEY && !lexer.isEnabled(Feature.DisableSpecialKeyDetect)) {
          String typeName = lexer.scanSymbol(symbolTable, '"');
          Class<?> clazz = TypeUtils.loadClass(typeName, config.getDefaultClassLoader());

          if (clazz == null) {
            object.put(JSON.DEFAULT_TYPE_KEY, typeName);
            continue;
          }

          lexer.nextToken(JSONToken.COMMA);
          if (lexer.token() == JSONToken.RBRACE) {
            lexer.nextToken(JSONToken.COMMA);
            try {
              Object instance = null;
              ObjectDeserializer deserializer = this.config.getDeserializer(clazz);
              if (deserializer instanceof JavaBeanDeserializer) {
                instance = ((JavaBeanDeserializer) deserializer).createInstance(this, clazz);
              }

              if (instance == null) {
                if (clazz == Cloneable.class) {
                  instance = new HashMap();
                } else if ("java.util.Collections$EmptyMap".equals(typeName)) {
                  instance = Collections.emptyMap();
                } else {
                  instance = clazz.newInstance();
                }
              }

              return instance;
            } catch (Exception e) {
              throw new JSONException("create instance error", e);
            }
          }

          this.setResolveStatus(TypeNameRedirect);

          if (this.context != null && !(fieldName instanceof Integer)) {
            this.popContext();
          }

          if (object.size() > 0) {
            Object newObj = TypeUtils.cast(object, clazz, this.config);
            this.parseObject(newObj);
            return newObj;
          }

          ObjectDeserializer deserializer = config.getDeserializer(clazz);
          return deserializer.deserialze(this, clazz, fieldName);
        }

        if (key == "$ref" && !lexer.isEnabled(Feature.DisableSpecialKeyDetect)) {
          lexer.nextToken(JSONToken.LITERAL_STRING);
          if (lexer.token() == JSONToken.LITERAL_STRING) {
            String ref = lexer.stringVal();
            lexer.nextToken(JSONToken.RBRACE);

            Object refValue = null;
            if ("@".equals(ref)) {
              if (this.context != null) {
                ParseContext thisContext = this.context;
                Object thisObj = thisContext.object;
                if (thisObj instanceof Object[] || thisObj instanceof Collection<?>) {
                  refValue = thisObj;
                } else if (thisContext.parent != null) {
                  refValue = thisContext.parent.object;
                }
              }
            } else if ("..".equals(ref)) {
              if (context.object != null) {
                refValue = context.object;
              } else {
                addResolveTask(new ResolveTask(context, ref));
                setResolveStatus(DefaultJSONParser.NeedToResolve);
              }
            } else if ("$".equals(ref)) {
              ParseContext rootContext = context;
              while (rootContext.parent != null) {
                rootContext = rootContext.parent;
              }

              if (rootContext.object != null) {
                refValue = rootContext.object;
              } else {
                addResolveTask(new ResolveTask(rootContext, ref));
                setResolveStatus(DefaultJSONParser.NeedToResolve);
              }
            } else {
              addResolveTask(new ResolveTask(context, ref));
              setResolveStatus(DefaultJSONParser.NeedToResolve);
            }

            if (lexer.token() != JSONToken.RBRACE) {
              throw new JSONException("syntax error");
            }
            lexer.nextToken(JSONToken.COMMA);

            return refValue;
          } else {
            throw new JSONException("illegal ref, " + JSONToken.name(lexer.token()));
          }
        }

        if (!setContextFlag) {
          ParseContext contextR = setContext(object, fieldName);
          if (context == null) {
            context = contextR;
          }
          setContextFlag = true;
        }

        if (object.getClass() == JSONObject.class) {
          key = (key == null) ? "null" : key.toString();
        }

        Object value;
        if (ch == '"') {
          lexer.scanString();
          String strValue = lexer.stringVal();
          value = strValue;

          if (lexer.isEnabled(Feature.AllowISO8601DateFormat)) {
            JSONScanner iso8601Lexer = new JSONScanner(strValue);
            if (iso8601Lexer.scanISO8601DateIfMatch()) {
              value = iso8601Lexer.getCalendar().getTime();
            }
            iso8601Lexer.close();
          }

          object.put(key, value);
        } else if (ch >= '0' && ch <= '9' || ch == '-') {
          lexer.scanNumber();
          if (lexer.token() == JSONToken.LITERAL_INT) {
            value = lexer.integerValue();
          } else {
            value = lexer.decimalValue(lexer.isEnabled(Feature.UseBigDecimal));
          }

          object.put(key, value);
        } else if (ch == '[') { // 减少嵌套,兼容android
          lexer.nextToken();
          JSONArray list = new JSONArray();
          this.parseArray(list, key);

          if (lexer.isEnabled(Feature.UseObjectArray)) {
            value = list.toArray();
          } else {
            value = list;
          }
          object.put(key, value);

          if (lexer.token() == JSONToken.RBRACE) {
            lexer.nextToken();
            return object;
          } else if (lexer.token() == JSONToken.COMMA) {
            continue;
          } else {
            throw new JSONException("syntax error");
          }
        } else if (ch == '{') { // 减少嵌套,兼容android
          lexer.nextToken();

          final boolean parentIsArray = fieldName != null && fieldName.getClass() == Integer.class;

          JSONObject input = new JSONObject(lexer.isEnabled(Feature.OrderedField));
          ParseContext ctxLocal = null;

          if (!parentIsArray) {
            ctxLocal = setContext(context, input, key);
          }

          Object obj = null;
          boolean objParsed = false;
          if (fieldTypeResolver != null) {
            String resolveFieldName = key != null ? key.toString() : null;
            Type fieldType = fieldTypeResolver.resolve(object, resolveFieldName);
            if (fieldType != null) {
              ObjectDeserializer fieldDeser = config.getDeserializer(fieldType);
              obj = fieldDeser.deserialze(this, fieldType, key);
              objParsed = true;
            }
          }
          if (!objParsed) {
            obj = this.parseObject(input, key);
          }

          if (ctxLocal != null && input != obj) {
            ctxLocal.object = object;
          }

          checkMapResolve(object, key.toString());

          if (object.getClass() == JSONObject.class) {
            object.put(key.toString(), obj);
          } else {
            object.put(key, obj);
          }

          if (parentIsArray) {
            // setContext(context, obj, key);
            setContext(obj, key);
          }

          if (lexer.token() == JSONToken.RBRACE) {
            lexer.nextToken();

            setContext(context);
            return object;
          } else if (lexer.token() == JSONToken.COMMA) {
            if (parentIsArray) {
              this.popContext();
            }
            continue;
          } else {
            throw new JSONException("syntax error, " + lexer.tokenName());
          }
        } else {
          lexer.nextToken();
          value = parse();

          if (object.getClass() == JSONObject.class) {
            key = key.toString();
          }
          object.put(key, value);

          if (lexer.token() == JSONToken.RBRACE) {
            lexer.nextToken();
            return object;
          } else if (lexer.token() == JSONToken.COMMA) {
            continue;
          } else {
            throw new JSONException("syntax error, position at " + lexer.pos() + ", name " + key);
          }
        }

        lexer.skipWhitespace();
        ch = lexer.getCurrent();
        if (ch == ',') {
          lexer.next();
          continue;
        } else if (ch == '}') {
          lexer.next();
          lexer.resetStringPosition();
          lexer.nextToken();

          // this.setContext(object, fieldName);
          this.setContext(value, key);

          return object;
        } else {
          throw new JSONException("syntax error, position at " + lexer.pos() + ", name " + key);
        }
      }
    } finally {
      this.setContext(context);
    }
  }