#ifndef GOOGLE_PROTOBUF_UTIL_INTERNAL_JSON_STREAM_PARSER_H__
#define GOOGLE_PROTOBUF_UTIL_INTERNAL_JSON_STREAM_PARSER_H__
#include <cstdint>
#include <stack>
#include <string>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/status.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/stubs/status.h>
#include <google/protobuf/port_def.inc>
namespace google {
namespace protobuf {
namespace util {
namespace converter {
class ObjectWriter;
class PROTOBUF_EXPORT JsonStreamParser {
public:
explicit JsonStreamParser(ObjectWriter* ow);
virtual ~JsonStreamParser();
util::Status Parse(StringPiece json);
util::Status FinishParse();
void set_max_recursion_depth(int max_depth) {
max_recursion_depth_ = max_depth;
}
enum ParseErrorType {
UNKNOWN_PARSE_ERROR,
OCTAL_OR_HEX_ARE_NOT_VALID_JSON_VALUES,
EXPECTED_COLON,
EXPECTED_COMMA_OR_BRACKET,
EXPECTED_VALUE,
EXPECTED_COMMA_OR_BRACES,
EXPECTED_OBJECT_KEY_OR_BRACES,
EXPECTED_VALUE_OR_BRACKET,
INVALID_KEY_OR_VARIABLE_NAME,
NON_UTF_8,
PARSING_TERMINATED_BEFORE_END_OF_INPUT,
UNEXPECTED_TOKEN,
EXPECTED_CLOSING_QUOTE,
ILLEGAL_HEX_STRING,
INVALID_ESCAPE_SEQUENCE,
MISSING_LOW_SURROGATE,
INVALID_LOW_SURROGATE,
INVALID_UNICODE,
UNABLE_TO_PARSE_NUMBER,
NUMBER_EXCEEDS_RANGE_DOUBLE
};
private:
friend class JsonStreamParserTest;
int recursion_depth() { return recursion_depth_; }
enum TokenType {
BEGIN_STRING, BEGIN_NUMBER, BEGIN_TRUE, BEGIN_FALSE, BEGIN_NULL, BEGIN_OBJECT, END_OBJECT, BEGIN_ARRAY, END_ARRAY, ENTRY_SEPARATOR, VALUE_SEPARATOR, BEGIN_KEY, UNKNOWN };
enum ParseType {
VALUE, OBJ_MID, ENTRY, ENTRY_MID, ARRAY_VALUE, ARRAY_MID };
struct NumberResult {
enum Type { DOUBLE, INT, UINT };
Type type;
union {
double double_val;
int64_t int_val;
uint64_t uint_val;
};
};
util::Status ParseChunk(StringPiece chunk);
util::Status RunParser();
util::Status ParseValue(TokenType type);
util::Status ParseString();
util::Status ParseStringHelper();
util::Status ParseUnicodeEscape();
util::Status ParseNumber();
util::Status ParseNumberHelper(NumberResult* result);
util::Status ParseDoubleHelper(const std::string& number,
NumberResult* result);
util::Status HandleBeginObject();
util::Status ParseEntry(TokenType type);
util::Status ParseEntryMid(TokenType type);
util::Status ParseObjectMid(TokenType type);
util::Status HandleBeginArray();
util::Status ParseArrayValue(TokenType type);
util::Status ParseArrayMid(TokenType type);
util::Status ParseTrue();
util::Status ParseFalse();
util::Status ParseNull();
util::Status ParseEmptyNull();
bool IsEmptyNullAllowed(TokenType type);
bool IsInputAllWhiteSpaces(TokenType type);
util::Status ReportFailure(StringPiece message,
ParseErrorType parse_code);
util::Status ReportUnknown(StringPiece message,
ParseErrorType parse_code);
util::Status IncrementRecursionDepth(StringPiece key) const;
void SkipWhitespace();
void Advance();
util::Status ParseKey();
TokenType GetNextTokenType();
ObjectWriter* ow_;
std::stack<ParseType> stack_;
std::string leftover_;
StringPiece json_;
StringPiece p_;
StringPiece key_;
std::string key_storage_;
bool finishing_;
bool seen_non_whitespace_;
bool allow_no_root_element_;
StringPiece parsed_;
std::string parsed_storage_;
char string_open_;
std::string chunk_storage_;
bool coerce_to_utf8_;
std::string utf8_replacement_character_;
bool allow_empty_null_;
bool allow_permissive_key_naming_;
bool loose_float_number_conversion_;
mutable int recursion_depth_;
int max_recursion_depth_;
GOOGLE_DISALLOW_IMPLICIT_CONSTRUCTORS(JsonStreamParser);
};
} } } }
#include <google/protobuf/port_undef.inc>
#endif