1 // Copyright 2012 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef BASE_JSON_JSON_PARSER_H_
6 #define BASE_JSON_JSON_PARSER_H_
14 #include "base/base_export.h"
15 #include "base/compiler_specific.h"
16 #include "base/gtest_prod_util.h"
17 #include "base/json/json_common.h"
18 #include "base/strings/string_piece.h"
19 #include "base/third_party/icu/icu_utf.h"
20 #include "base/values.h"
21 #include "third_party/abseil-cpp/absl/types/optional.h"
31 // The implementation behind the JSONReader interface. This class is not meant
32 // to be used directly; it encapsulates logic that need not be exposed publicly.
34 // This parser guarantees O(n) time through the input string. Iteration happens
35 // on the byte level, with the functions ConsumeChars() and ConsumeChar(). The
36 // conversion from byte to JSON token happens without advancing the parser in
37 // GetNextToken/ParseToken, that is tokenization operates on the current parser
38 // position without advancing.
40 // Built on top of these are a family of Consume functions that iterate
41 // internally. Invariant: on entry of a Consume function, the parser is wound
42 // to the first byte of a valid JSON token. On exit, it is on the first byte
43 // after the token that was just consumed, which would likely be the first byte
45 class BASE_EXPORT JSONParser {
47 // Error codes during parsing.
49 JSON_NO_ERROR = base::ValueDeserializer::kErrorCodeNoError,
50 JSON_SYNTAX_ERROR = base::ValueDeserializer::kErrorCodeInvalidFormat,
52 JSON_UNEXPECTED_TOKEN,
54 JSON_TOO_MUCH_NESTING,
55 JSON_UNEXPECTED_DATA_AFTER_ROOT,
56 JSON_UNSUPPORTED_ENCODING,
57 JSON_UNQUOTED_DICTIONARY_KEY,
58 JSON_UNREPRESENTABLE_NUMBER,
59 JSON_PARSE_ERROR_COUNT
62 // String versions of parse error codes.
63 static const char kSyntaxError[];
64 static const char kInvalidEscape[];
65 static const char kUnexpectedToken[];
66 static const char kTrailingComma[];
67 static const char kTooMuchNesting[];
68 static const char kUnexpectedDataAfterRoot[];
69 static const char kUnsupportedEncoding[];
70 static const char kUnquotedDictionaryKey[];
71 static const char kUnrepresentableNumber[];
73 explicit JSONParser(int options, size_t max_depth = kAbsoluteMaxDepth);
75 JSONParser(const JSONParser&) = delete;
76 JSONParser& operator=(const JSONParser&) = delete;
80 // Parses the input string according to the set options and returns the
82 // Wrap this in base::FooValue::From() to check the Value is of type Foo and
83 // convert to a FooValue at the same time.
84 absl::optional<Value> Parse(StringPiece input);
86 // Returns the error code.
87 JsonParseError error_code() const;
89 // Returns the human-friendly error message.
90 std::string GetErrorMessage() const;
92 // Returns the error line number if parse error happened. Otherwise always
94 int error_line() const;
96 // Returns the error column number if parse error happened. Otherwise always
98 int error_column() const;
109 T_BOOL_FALSE, // false
111 T_LIST_SEPARATOR, // ,
112 T_OBJECT_PAIR_SEPARATOR, // :
117 // A helper class used for parsing strings. One optimization performed is to
118 // create base::Value with a StringPiece to avoid unnecessary std::string
119 // copies. This is not possible if the input string needs to be decoded from
120 // UTF-16 to UTF-8, or if an escape sequence causes characters to be skipped.
121 // This class centralizes that logic.
122 class StringBuilder {
124 // Empty constructor. Used for creating a builder with which to assign to.
127 // |pos| is the beginning of an input string, excluding the |"|.
128 explicit StringBuilder(const char* pos);
132 StringBuilder& operator=(StringBuilder&& other);
134 // Appends the Unicode code point |point| to the string, either by
135 // increasing the |length_| of the string if the string has not been
136 // converted, or by appending the UTF8 bytes for the code point.
137 void Append(base_icu::UChar32 point);
139 // Converts the builder from its default StringPiece to a full std::string,
140 // performing a copy. Once a builder is converted, it cannot be made a
141 // StringPiece again.
144 // Returns the builder as a string, invalidating all state. This allows
145 // the internal string buffer representation to be destructively moved
146 // in cases where the builder will not be needed any more.
147 std::string DestructiveAsString();
150 // The beginning of the input string.
153 // Number of bytes in |pos_| that make up the string being built.
156 // The copied string representation. Will be unset until Convert() is
158 absl::optional<std::string> string_;
161 // Returns the next |count| bytes of the input stream, or nullopt if fewer
162 // than |count| bytes remain.
163 absl::optional<StringPiece> PeekChars(size_t count);
165 // Calls PeekChars() with a |count| of 1.
166 absl::optional<char> PeekChar();
168 // Returns the next |count| bytes of the input stream, or nullopt if fewer
169 // than |count| bytes remain, and advances the parser position by |count|.
170 absl::optional<StringPiece> ConsumeChars(size_t count);
172 // Calls ConsumeChars() with a |count| of 1.
173 absl::optional<char> ConsumeChar();
175 // Returns a pointer to the current character position.
178 // Skips over whitespace and comments to find the next token in the stream.
179 // This does not advance the parser for non-whitespace or comment chars.
180 Token GetNextToken();
182 // Consumes whitespace characters and comments until the next non-that is
184 void EatWhitespaceAndComments();
185 // Helper function that consumes a comment, assuming that the parser is
186 // currently wound to a '/'.
189 // Calls GetNextToken() and then ParseToken().
190 absl::optional<Value> ParseNextToken();
192 // Takes a token that represents the start of a Value ("a structural token"
193 // in RFC terms) and consumes it, returning the result as a Value.
194 absl::optional<Value> ParseToken(Token token);
196 // Assuming that the parser is currently wound to '{', this parses a JSON
197 // object into a Value.
198 absl::optional<Value> ConsumeDictionary();
200 // Assuming that the parser is wound to '[', this parses a JSON list into a
202 absl::optional<Value> ConsumeList();
204 // Calls through ConsumeStringRaw and wraps it in a value.
205 absl::optional<Value> ConsumeString();
207 // Assuming that the parser is wound to a double quote, this parses a string,
208 // decoding any escape sequences and converts UTF-16 to UTF-8. Returns true on
209 // success and places result into |out|. Returns false on failure with
210 // error information set.
211 bool ConsumeStringRaw(StringBuilder* out);
212 // Helper function for ConsumeStringRaw() that consumes the next four or 10
213 // bytes (parser is wound to the first character of a HEX sequence, with the
214 // potential for consuming another \uXXXX for a surrogate). Returns true on
215 // success and places the code point |out_code_point|, and false on failure.
216 bool DecodeUTF16(base_icu::UChar32* out_code_point);
218 // Assuming that the parser is wound to the start of a valid JSON number,
219 // this parses and converts it to either an int or double value.
220 absl::optional<Value> ConsumeNumber();
221 // Helper that reads characters that are ints. Returns true if a number was
222 // read and false on error.
223 bool ReadInt(bool allow_leading_zeros);
225 // Consumes the literal values of |true|, |false|, and |null|, assuming the
226 // parser is wound to the first character of any of those.
227 absl::optional<Value> ConsumeLiteral();
229 // Helper function that returns true if the byte squence |match| can be
230 // consumed at the current parser position. Returns false if there are fewer
231 // than |match|-length bytes or if the sequence does not match, and the
232 // parser state is unchanged.
233 bool ConsumeIfMatch(StringPiece match);
235 // Sets the error information to |code| at the current column, based on
236 // |index_| and |index_last_line_|, with an optional positive/negative
237 // adjustment by |column_adjust|.
238 void ReportError(JsonParseError code, int column_adjust);
240 // Given the line and column number of an error, formats one of the error
241 // message contants from json_reader.h for human display.
242 static std::string FormatErrorMessage(int line, int column,
243 const std::string& description);
245 // base::JSONParserOptions that control parsing.
248 // Maximum depth to parse.
249 const size_t max_depth_;
251 // The input stream being parsed. Note: Not guaranteed to NUL-terminated.
254 // The index in the input stream to which the parser is wound.
257 // The number of times the parser has recursed (current stack depth).
260 // The line number that the parser is at currently.
263 // The last value of |index_| on the previous line.
264 size_t index_last_line_;
266 // Error information.
267 JsonParseError error_code_;
271 friend class JSONParserTest;
272 FRIEND_TEST_ALL_PREFIXES(JSONParserTest, NextChar);
273 FRIEND_TEST_ALL_PREFIXES(JSONParserTest, ConsumeDictionary);
274 FRIEND_TEST_ALL_PREFIXES(JSONParserTest, ConsumeList);
275 FRIEND_TEST_ALL_PREFIXES(JSONParserTest, ConsumeString);
276 FRIEND_TEST_ALL_PREFIXES(JSONParserTest, ConsumeLiterals);
277 FRIEND_TEST_ALL_PREFIXES(JSONParserTest, ConsumeNumbers);
278 FRIEND_TEST_ALL_PREFIXES(JSONParserTest, ErrorMessages);
281 // Used when decoding and an invalid utf-8 sequence is encountered.
282 BASE_EXPORT extern const char kUnicodeReplacementString[];
284 } // namespace internal
287 #endif // BASE_JSON_JSON_PARSER_H_