text: // Copyright (c) 2012 The Chromium Authors. All rights reserved.
  // Use of this source code is governed by a BSD-style license that can be
  // found in the LICENSE file.
  
  #include "base/json/json_reader.h"
  
  #include <utility>
  #include <vector>
  
  #include "base/json/json_parser.h"
  #include "base/logging.h"
  #include "base/optional.h"
  
  namespace base {
  
  // Chosen to support 99.9% of documents found in the wild late 2016.
  // http://crbug.com/673263
  const int JSONReader::kStackMaxDepth = 200;
  
  // Values 1000 and above are used by JSONFileValueSerializer::JsonFileError.
  static_assert(JSONReader::JSON_PARSE_ERROR_COUNT < 1000,
                "JSONReader error out of bounds");
  
  const char JSONReader::kInvalidEscape[] =
      "Invalid escape sequence.";
  const char JSONReader::kSyntaxError[] =
      "Syntax error.";
  const char JSONReader::kUnexpectedToken[] =
      "Unexpected token.";
  const char JSONReader::kTrailingComma[] =
      "Trailing comma not allowed.";
  const char JSONReader::kTooMuchNesting[] =
      "Too much nesting.";
  const char JSONReader::kUnexpectedDataAfterRoot[] =
      "Unexpected data after root element.";
  const char JSONReader::kUnsupportedEncoding[] =
      "Unsupported encoding. JSON must be UTF-8.";
  const char JSONReader::kUnquotedDictionaryKey[] =
      "Dictionary keys must be quoted.";
  const char JSONReader::kInputTooLarge[] =
      "Input string is too large (>2GB).";
  
  JSONReader::ValueWithError::ValueWithError() = default;
  
  JSONReader::ValueWithError::ValueWithError(ValueWithError&& other) = default;
  
  JSONReader::ValueWithError::~ValueWithError() = default;
  
  JSONReader::ValueWithError& JSONReader::ValueWithError::operator=(
      ValueWithError&& other) = default;
  
  JSONReader::JSONReader(int options, int max_depth)
      : parser_(new internal::JSONParser(options, max_depth)) {}
  
  JSONReader::~JSONReader() = default;
  
  // static
  Optional<Value> JSONReader::Read(StringPiece json, int options, int max_depth) {
    internal::JSONParser parser(options, max_depth);
    return parser.Parse(json);
  }
  
  std::unique_ptr<Value> JSONReader::ReadDeprecated(StringPiece json,
                                                    int options,
                                                    int max_depth) {
    Optional<Value> value = Read(json, options, max_depth);
    return value ? Value::ToUniquePtrValue(std::move(*value)) : nullptr;
  }
  
  // static
  JSONReader::ValueWithError JSONReader::ReadAndReturnValueWithError(
      StringPiece json,
      int options) {
    ValueWithError ret;
    internal::JSONParser parser(options);
    ret.value = parser.Parse(json);
    if (!ret.value) {
      ret.error_message = parser.GetErrorMessage();
      ret.error_code = parser.error_code();
      ret.error_line = parser.error_line();
      ret.error_column = parser.error_column();
    }
    return ret;
  }
  
  // static
  std::unique_ptr<Value> JSONReader::ReadAndReturnErrorDeprecated(
      StringPiece json,
      int options,
      int* error_code_out,
      std::string* error_msg_out,
      int* error_line_out,
      int* error_column_out) {
    ValueWithError ret = ReadAndReturnValueWithError(json, options);
    if (ret.value)
      return Value::ToUniquePtrValue(std::move(*ret.value));
  
    if (error_code_out)
      *error_code_out = ret.error_code;
    if (error_msg_out)
      *error_msg_out = ret.error_message;
    if (error_line_out)
      *error_line_out = ret.error_line;
    if (error_column_out)
      *error_column_out = ret.error_column;
    return nullptr;
  }
  
  // static
  std::string JSONReader::ErrorCodeToString(JsonParseError error_code) {
    switch (error_code) {
      case JSON_NO_ERROR:
        return std::string();
      case JSON_INVALID_ESCAPE:
        return kInvalidEscape;
      case JSON_SYNTAX_ERROR:
        return kSyntaxError;
      case JSON_UNEXPECTED_TOKEN:
        return kUnexpectedToken;
      case JSON_TRAILING_COMMA:
        return kTrailingComma;
      case JSON_TOO_MUCH_NESTING:
        return kTooMuchNesting;
      case JSON_UNEXPECTED_DATA_AFTER_ROOT:
        return kUnexpectedDataAfterRoot;
      case JSON_UNSUPPORTED_ENCODING:
        return kUnsupportedEncoding;
      case JSON_UNQUOTED_DICTIONARY_KEY:
        return kUnquotedDictionaryKey;
      case JSON_TOO_LARGE:
        return kInputTooLarge;
      case JSON_PARSE_ERROR_COUNT:
        break;
    }
    NOTREACHED();
    return std::string();
  }
  
  Optional<Value> JSONReader::ReadToValue(StringPiece json) {
    return parser_->Parse(json);
  }
  
  std::unique_ptr<Value> JSONReader::ReadToValueDeprecated(StringPiece json) {
    Optional<Value> value = parser_->Parse(json);
    return value ? std::make_unique<Value>(std::move(*value)) : nullptr;
  }
  
  JSONReader::JsonParseError JSONReader::error_code() const {
    return parser_->error_code();
  }
  
  std::string JSONReader::GetErrorMessage() const {
    return parser_->GetErrorMessage();
  }
  
  }  // namespace base
  