16d528ed9Sopenharmony_ci// Copyright (c) 2012 The Chromium Authors. All rights reserved.
26d528ed9Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
36d528ed9Sopenharmony_ci// found in the LICENSE file.
46d528ed9Sopenharmony_ci//
56d528ed9Sopenharmony_ci// A JSON parser.  Converts strings of JSON into a Value object (see
66d528ed9Sopenharmony_ci// base/values.h).
76d528ed9Sopenharmony_ci// http://www.ietf.org/rfc/rfc4627.txt?number=4627
86d528ed9Sopenharmony_ci//
96d528ed9Sopenharmony_ci// Known limitations/deviations from the RFC:
106d528ed9Sopenharmony_ci// - Only knows how to parse ints within the range of a signed 32 bit int and
116d528ed9Sopenharmony_ci//   decimal numbers within a double.
126d528ed9Sopenharmony_ci// - Assumes input is encoded as UTF8.  The spec says we should allow UTF-16
136d528ed9Sopenharmony_ci//   (BE or LE) and UTF-32 (BE or LE) as well.
146d528ed9Sopenharmony_ci// - We limit nesting to 100 levels to prevent stack overflow (this is allowed
156d528ed9Sopenharmony_ci//   by the RFC).
166d528ed9Sopenharmony_ci// - A Unicode FAQ ("http://unicode.org/faq/utf_bom.html") writes a data
176d528ed9Sopenharmony_ci//   stream may start with a Unicode Byte-Order-Mark (U+FEFF), i.e. the input
186d528ed9Sopenharmony_ci//   UTF-8 string for the JSONReader::JsonToValue() function may start with a
196d528ed9Sopenharmony_ci//   UTF-8 BOM (0xEF, 0xBB, 0xBF).
206d528ed9Sopenharmony_ci//   To avoid the function from mis-treating a UTF-8 BOM as an invalid
216d528ed9Sopenharmony_ci//   character, the function skips a Unicode BOM at the beginning of the
226d528ed9Sopenharmony_ci//   Unicode string (converted from the input UTF-8 string) before parsing it.
236d528ed9Sopenharmony_ci//
246d528ed9Sopenharmony_ci// TODO(tc): Add a parsing option to to relax object keys being wrapped in
256d528ed9Sopenharmony_ci//   double quotes
266d528ed9Sopenharmony_ci// TODO(tc): Add an option to disable comment stripping
276d528ed9Sopenharmony_ci
286d528ed9Sopenharmony_ci#ifndef BASE_JSON_JSON_READER_H_
296d528ed9Sopenharmony_ci#define BASE_JSON_JSON_READER_H_
306d528ed9Sopenharmony_ci
316d528ed9Sopenharmony_ci#include <memory>
326d528ed9Sopenharmony_ci#include <string>
336d528ed9Sopenharmony_ci#include <string_view>
346d528ed9Sopenharmony_ci
356d528ed9Sopenharmony_cinamespace base {
366d528ed9Sopenharmony_ci
376d528ed9Sopenharmony_ciclass Value;
386d528ed9Sopenharmony_ci
396d528ed9Sopenharmony_cinamespace internal {
406d528ed9Sopenharmony_ciclass JSONParser;
416d528ed9Sopenharmony_ci}
426d528ed9Sopenharmony_ci
436d528ed9Sopenharmony_cienum JSONParserOptions {
446d528ed9Sopenharmony_ci  // Parses the input strictly according to RFC 4627, except for where noted
456d528ed9Sopenharmony_ci  // above.
466d528ed9Sopenharmony_ci  JSON_PARSE_RFC = 0,
476d528ed9Sopenharmony_ci
486d528ed9Sopenharmony_ci  // Allows commas to exist after the last element in structures.
496d528ed9Sopenharmony_ci  JSON_ALLOW_TRAILING_COMMAS = 1 << 0,
506d528ed9Sopenharmony_ci
516d528ed9Sopenharmony_ci  // If set the parser replaces invalid characters with the Unicode replacement
526d528ed9Sopenharmony_ci  // character (U+FFFD). If not set, invalid characters trigger a hard error and
536d528ed9Sopenharmony_ci  // parsing fails.
546d528ed9Sopenharmony_ci  JSON_REPLACE_INVALID_CHARACTERS = 1 << 1,
556d528ed9Sopenharmony_ci};
566d528ed9Sopenharmony_ci
576d528ed9Sopenharmony_ciclass JSONReader {
586d528ed9Sopenharmony_ci public:
596d528ed9Sopenharmony_ci  static const int kStackMaxDepth;
606d528ed9Sopenharmony_ci
616d528ed9Sopenharmony_ci  // Error codes during parsing.
626d528ed9Sopenharmony_ci  enum JsonParseError {
636d528ed9Sopenharmony_ci    JSON_NO_ERROR = 0,
646d528ed9Sopenharmony_ci    JSON_INVALID_ESCAPE,
656d528ed9Sopenharmony_ci    JSON_SYNTAX_ERROR,
666d528ed9Sopenharmony_ci    JSON_UNEXPECTED_TOKEN,
676d528ed9Sopenharmony_ci    JSON_TRAILING_COMMA,
686d528ed9Sopenharmony_ci    JSON_TOO_MUCH_NESTING,
696d528ed9Sopenharmony_ci    JSON_UNEXPECTED_DATA_AFTER_ROOT,
706d528ed9Sopenharmony_ci    JSON_UNSUPPORTED_ENCODING,
716d528ed9Sopenharmony_ci    JSON_UNQUOTED_DICTIONARY_KEY,
726d528ed9Sopenharmony_ci    JSON_TOO_LARGE,
736d528ed9Sopenharmony_ci    JSON_PARSE_ERROR_COUNT
746d528ed9Sopenharmony_ci  };
756d528ed9Sopenharmony_ci
766d528ed9Sopenharmony_ci  // String versions of parse error codes.
776d528ed9Sopenharmony_ci  static const char kInvalidEscape[];
786d528ed9Sopenharmony_ci  static const char kSyntaxError[];
796d528ed9Sopenharmony_ci  static const char kUnexpectedToken[];
806d528ed9Sopenharmony_ci  static const char kTrailingComma[];
816d528ed9Sopenharmony_ci  static const char kTooMuchNesting[];
826d528ed9Sopenharmony_ci  static const char kUnexpectedDataAfterRoot[];
836d528ed9Sopenharmony_ci  static const char kUnsupportedEncoding[];
846d528ed9Sopenharmony_ci  static const char kUnquotedDictionaryKey[];
856d528ed9Sopenharmony_ci  static const char kInputTooLarge[];
866d528ed9Sopenharmony_ci
876d528ed9Sopenharmony_ci  // Constructs a reader.
886d528ed9Sopenharmony_ci  JSONReader(int options = JSON_PARSE_RFC, int max_depth = kStackMaxDepth);
896d528ed9Sopenharmony_ci
906d528ed9Sopenharmony_ci  ~JSONReader();
916d528ed9Sopenharmony_ci
926d528ed9Sopenharmony_ci  // Reads and parses |json|, returning a Value.
936d528ed9Sopenharmony_ci  // If |json| is not a properly formed JSON string, returns nullptr.
946d528ed9Sopenharmony_ci  // Wrap this in base::FooValue::From() to check the Value is of type Foo and
956d528ed9Sopenharmony_ci  // convert to a FooValue at the same time.
966d528ed9Sopenharmony_ci  static std::unique_ptr<Value> Read(std::string_view json,
976d528ed9Sopenharmony_ci                                     int options = JSON_PARSE_RFC,
986d528ed9Sopenharmony_ci                                     int max_depth = kStackMaxDepth);
996d528ed9Sopenharmony_ci
1006d528ed9Sopenharmony_ci  // Reads and parses |json| like Read(). |error_code_out| and |error_msg_out|
1016d528ed9Sopenharmony_ci  // are optional. If specified and nullptr is returned, they will be populated
1026d528ed9Sopenharmony_ci  // an error code and a formatted error message (including error location if
1036d528ed9Sopenharmony_ci  // appropriate). Otherwise, they will be unmodified.
1046d528ed9Sopenharmony_ci  static std::unique_ptr<Value> ReadAndReturnError(
1056d528ed9Sopenharmony_ci      std::string_view json,
1066d528ed9Sopenharmony_ci      int options,  // JSONParserOptions
1076d528ed9Sopenharmony_ci      int* error_code_out,
1086d528ed9Sopenharmony_ci      std::string* error_msg_out,
1096d528ed9Sopenharmony_ci      int* error_line_out = nullptr,
1106d528ed9Sopenharmony_ci      int* error_column_out = nullptr);
1116d528ed9Sopenharmony_ci
1126d528ed9Sopenharmony_ci  // Converts a JSON parse error code into a human readable message.
1136d528ed9Sopenharmony_ci  // Returns an empty string if error_code is JSON_NO_ERROR.
1146d528ed9Sopenharmony_ci  static std::string ErrorCodeToString(JsonParseError error_code);
1156d528ed9Sopenharmony_ci
1166d528ed9Sopenharmony_ci  // Non-static version of Read() above.
1176d528ed9Sopenharmony_ci  std::unique_ptr<Value> ReadToValue(std::string_view json);
1186d528ed9Sopenharmony_ci
1196d528ed9Sopenharmony_ci  // Returns the error code if the last call to ReadToValue() failed.
1206d528ed9Sopenharmony_ci  // Returns JSON_NO_ERROR otherwise.
1216d528ed9Sopenharmony_ci  JsonParseError error_code() const;
1226d528ed9Sopenharmony_ci
1236d528ed9Sopenharmony_ci  // Converts error_code_ to a human-readable string, including line and column
1246d528ed9Sopenharmony_ci  // numbers if appropriate.
1256d528ed9Sopenharmony_ci  std::string GetErrorMessage() const;
1266d528ed9Sopenharmony_ci
1276d528ed9Sopenharmony_ci private:
1286d528ed9Sopenharmony_ci  std::unique_ptr<internal::JSONParser> parser_;
1296d528ed9Sopenharmony_ci};
1306d528ed9Sopenharmony_ci
1316d528ed9Sopenharmony_ci}  // namespace base
1326d528ed9Sopenharmony_ci
1336d528ed9Sopenharmony_ci#endif  // BASE_JSON_JSON_READER_H_
134