private JsonToken next() throws JsonParseException {

    if (!context.hasValue() && state() == AbstractBsonReader.State.VALUE) {
      // means the value was not parsed before and can be skipped
      reader.skipValue();
    }

    context.reset();

    while (state() == AbstractBsonReader.State.TYPE) {
      reader.readBsonType();
    }

    switch (state()) {
      case INITIAL:
        reader.readStartDocument();
        return JsonToken.START_OBJECT;
      case NAME:
        context.fieldName = reader.readName();
        context.skipValue = false; // next token can be VALUE don't skip
        return JsonToken.FIELD_NAME;
      case END_OF_DOCUMENT:
        reader.readEndDocument();
        return JsonToken.END_OBJECT;
      case END_OF_ARRAY:
        reader.readEndArray();
        return JsonToken.END_ARRAY;
      case DONE:
        return null;
      case VALUE:
        return readToken();
      default:
        throw new JsonParseException(this, String.format("Unexpected BSON state:%s type:%s", state(), type()));
    }
  }
Read (parse) current bson value and stored it in local {@link ParseContext} cache.
criteria/mongo/src/org/immutables/criteria/mongo/bson4jackson/BsonParser.java