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#ifndef BASE_JSON_JSON_VALUE_CONVERTER_H_
66d528ed9Sopenharmony_ci#define BASE_JSON_JSON_VALUE_CONVERTER_H_
76d528ed9Sopenharmony_ci
86d528ed9Sopenharmony_ci#include <stddef.h>
96d528ed9Sopenharmony_ci
106d528ed9Sopenharmony_ci#include <memory>
116d528ed9Sopenharmony_ci#include <string>
126d528ed9Sopenharmony_ci#include <string_view>
136d528ed9Sopenharmony_ci#include <vector>
146d528ed9Sopenharmony_ci
156d528ed9Sopenharmony_ci#include "base/logging.h"
166d528ed9Sopenharmony_ci#include "base/memory/ptr_util.h"
176d528ed9Sopenharmony_ci#include "base/values.h"
186d528ed9Sopenharmony_ci
196d528ed9Sopenharmony_ci// JSONValueConverter converts a JSON value into a C++ struct in a
206d528ed9Sopenharmony_ci// lightweight way.
216d528ed9Sopenharmony_ci//
226d528ed9Sopenharmony_ci// Usage:
236d528ed9Sopenharmony_ci// For real examples, you may want to refer to _unittest.cc file.
246d528ed9Sopenharmony_ci//
256d528ed9Sopenharmony_ci// Assume that you have a struct like this:
266d528ed9Sopenharmony_ci//   struct Message {
276d528ed9Sopenharmony_ci//     int foo;
286d528ed9Sopenharmony_ci//     std::string bar;
296d528ed9Sopenharmony_ci//     static void RegisterJSONConverter(
306d528ed9Sopenharmony_ci//         JSONValueConverter<Message>* converter);
316d528ed9Sopenharmony_ci//   };
326d528ed9Sopenharmony_ci//
336d528ed9Sopenharmony_ci// And you want to parse a json data into this struct.  First, you
346d528ed9Sopenharmony_ci// need to declare RegisterJSONConverter() method in your struct.
356d528ed9Sopenharmony_ci//   // static
366d528ed9Sopenharmony_ci//   void Message::RegisterJSONConverter(
376d528ed9Sopenharmony_ci//       JSONValueConverter<Message>* converter) {
386d528ed9Sopenharmony_ci//     converter->RegisterIntField("foo", &Message::foo);
396d528ed9Sopenharmony_ci//     converter->RegisterStringField("bar", &Message::bar);
406d528ed9Sopenharmony_ci//   }
416d528ed9Sopenharmony_ci//
426d528ed9Sopenharmony_ci// Then, you just instantiate your JSONValueConverter of your type and call
436d528ed9Sopenharmony_ci// Convert() method.
446d528ed9Sopenharmony_ci//   Message message;
456d528ed9Sopenharmony_ci//   JSONValueConverter<Message> converter;
466d528ed9Sopenharmony_ci//   converter.Convert(json, &message);
476d528ed9Sopenharmony_ci//
486d528ed9Sopenharmony_ci// Convert() returns false when it fails.  Here "fail" means that the value is
496d528ed9Sopenharmony_ci// structurally different from expected, such like a string value appears
506d528ed9Sopenharmony_ci// for an int field.  Do not report failures for missing fields.
516d528ed9Sopenharmony_ci// Also note that Convert() will modify the passed |message| even when it
526d528ed9Sopenharmony_ci// fails for performance reason.
536d528ed9Sopenharmony_ci//
546d528ed9Sopenharmony_ci// For nested field, the internal message also has to implement the registration
556d528ed9Sopenharmony_ci// method.  Then, just use RegisterNestedField() from the containing struct's
566d528ed9Sopenharmony_ci// RegisterJSONConverter method.
576d528ed9Sopenharmony_ci//   struct Nested {
586d528ed9Sopenharmony_ci//     Message foo;
596d528ed9Sopenharmony_ci//     static void RegisterJSONConverter(...) {
606d528ed9Sopenharmony_ci//       ...
616d528ed9Sopenharmony_ci//       converter->RegisterNestedField("foo", &Nested::foo);
626d528ed9Sopenharmony_ci//     }
636d528ed9Sopenharmony_ci//   };
646d528ed9Sopenharmony_ci//
656d528ed9Sopenharmony_ci// For repeated field, we just assume std::vector<std::unique_ptr<ElementType>>
666d528ed9Sopenharmony_ci// for its container and you can put RegisterRepeatedInt or some other types.
676d528ed9Sopenharmony_ci// Use RegisterRepeatedMessage for nested repeated fields.
686d528ed9Sopenharmony_ci//
696d528ed9Sopenharmony_ci// Sometimes JSON format uses string representations for other types such
706d528ed9Sopenharmony_ci// like enum, timestamp, or URL.  You can use RegisterCustomField method
716d528ed9Sopenharmony_ci// and specify a function to convert a std::string_view to your type.
726d528ed9Sopenharmony_ci//   bool ConvertFunc(std::string_view s, YourEnum* result) {
736d528ed9Sopenharmony_ci//     // do something and return true if succeed...
746d528ed9Sopenharmony_ci//   }
756d528ed9Sopenharmony_ci//   struct Message {
766d528ed9Sopenharmony_ci//     YourEnum ye;
776d528ed9Sopenharmony_ci//     ...
786d528ed9Sopenharmony_ci//     static void RegisterJSONConverter(...) {
796d528ed9Sopenharmony_ci//       ...
806d528ed9Sopenharmony_ci//       converter->RegsiterCustomField<YourEnum>(
816d528ed9Sopenharmony_ci//           "your_enum", &Message::ye, &ConvertFunc);
826d528ed9Sopenharmony_ci//     }
836d528ed9Sopenharmony_ci//   };
846d528ed9Sopenharmony_ci
856d528ed9Sopenharmony_cinamespace base {
866d528ed9Sopenharmony_ci
876d528ed9Sopenharmony_citemplate <typename StructType>
886d528ed9Sopenharmony_ciclass JSONValueConverter;
896d528ed9Sopenharmony_ci
906d528ed9Sopenharmony_cinamespace internal {
916d528ed9Sopenharmony_ci
926d528ed9Sopenharmony_citemplate <typename StructType>
936d528ed9Sopenharmony_ciclass FieldConverterBase {
946d528ed9Sopenharmony_ci public:
956d528ed9Sopenharmony_ci  explicit FieldConverterBase(const std::string& path) : field_path_(path) {}
966d528ed9Sopenharmony_ci  virtual ~FieldConverterBase() = default;
976d528ed9Sopenharmony_ci  virtual bool ConvertField(const base::Value& value,
986d528ed9Sopenharmony_ci                            StructType* obj) const = 0;
996d528ed9Sopenharmony_ci  const std::string& field_path() const { return field_path_; }
1006d528ed9Sopenharmony_ci
1016d528ed9Sopenharmony_ci private:
1026d528ed9Sopenharmony_ci  std::string field_path_;
1036d528ed9Sopenharmony_ci  FieldConverterBase(const FieldConverterBase&) = delete;
1046d528ed9Sopenharmony_ci  FieldConverterBase& operator=(const FieldConverterBase&) = delete;
1056d528ed9Sopenharmony_ci};
1066d528ed9Sopenharmony_ci
1076d528ed9Sopenharmony_citemplate <typename FieldType>
1086d528ed9Sopenharmony_ciclass ValueConverter {
1096d528ed9Sopenharmony_ci public:
1106d528ed9Sopenharmony_ci  virtual ~ValueConverter() = default;
1116d528ed9Sopenharmony_ci  virtual bool Convert(const base::Value& value, FieldType* field) const = 0;
1126d528ed9Sopenharmony_ci};
1136d528ed9Sopenharmony_ci
1146d528ed9Sopenharmony_citemplate <typename StructType, typename FieldType>
1156d528ed9Sopenharmony_ciclass FieldConverter : public FieldConverterBase<StructType> {
1166d528ed9Sopenharmony_ci public:
1176d528ed9Sopenharmony_ci  explicit FieldConverter(const std::string& path,
1186d528ed9Sopenharmony_ci                          FieldType StructType::*field,
1196d528ed9Sopenharmony_ci                          ValueConverter<FieldType>* converter)
1206d528ed9Sopenharmony_ci      : FieldConverterBase<StructType>(path),
1216d528ed9Sopenharmony_ci        field_pointer_(field),
1226d528ed9Sopenharmony_ci        value_converter_(converter) {}
1236d528ed9Sopenharmony_ci
1246d528ed9Sopenharmony_ci  bool ConvertField(const base::Value& value, StructType* dst) const override {
1256d528ed9Sopenharmony_ci    return value_converter_->Convert(value, &(dst->*field_pointer_));
1266d528ed9Sopenharmony_ci  }
1276d528ed9Sopenharmony_ci
1286d528ed9Sopenharmony_ci private:
1296d528ed9Sopenharmony_ci  FieldType StructType::*field_pointer_;
1306d528ed9Sopenharmony_ci  std::unique_ptr<ValueConverter<FieldType>> value_converter_;
1316d528ed9Sopenharmony_ci  FieldConverter(const FieldConverter&) = delete;
1326d528ed9Sopenharmony_ci  FieldConverter& operator=(const FieldConverter&) = delete;
1336d528ed9Sopenharmony_ci};
1346d528ed9Sopenharmony_ci
1356d528ed9Sopenharmony_citemplate <typename FieldType>
1366d528ed9Sopenharmony_ciclass BasicValueConverter;
1376d528ed9Sopenharmony_ci
1386d528ed9Sopenharmony_citemplate <>
1396d528ed9Sopenharmony_ciclass BasicValueConverter<int> : public ValueConverter<int> {
1406d528ed9Sopenharmony_ci public:
1416d528ed9Sopenharmony_ci  BasicValueConverter() = default;
1426d528ed9Sopenharmony_ci
1436d528ed9Sopenharmony_ci  bool Convert(const base::Value& value, int* field) const override;
1446d528ed9Sopenharmony_ci
1456d528ed9Sopenharmony_ci private:
1466d528ed9Sopenharmony_ci  BasicValueConverter(const BasicValueConverter&) = delete;
1476d528ed9Sopenharmony_ci  BasicValueConverter& operator=(const BasicValueConverter&) = delete;
1486d528ed9Sopenharmony_ci};
1496d528ed9Sopenharmony_ci
1506d528ed9Sopenharmony_citemplate <>
1516d528ed9Sopenharmony_ciclass BasicValueConverter<std::string> : public ValueConverter<std::string> {
1526d528ed9Sopenharmony_ci public:
1536d528ed9Sopenharmony_ci  BasicValueConverter() = default;
1546d528ed9Sopenharmony_ci
1556d528ed9Sopenharmony_ci  bool Convert(const base::Value& value, std::string* field) const override;
1566d528ed9Sopenharmony_ci
1576d528ed9Sopenharmony_ci private:
1586d528ed9Sopenharmony_ci  BasicValueConverter(const BasicValueConverter&) = delete;
1596d528ed9Sopenharmony_ci  BasicValueConverter& operator=(const BasicValueConverter&) = delete;
1606d528ed9Sopenharmony_ci};
1616d528ed9Sopenharmony_ci
1626d528ed9Sopenharmony_citemplate <>
1636d528ed9Sopenharmony_ciclass BasicValueConverter<std::u16string>
1646d528ed9Sopenharmony_ci    : public ValueConverter<std::u16string> {
1656d528ed9Sopenharmony_ci public:
1666d528ed9Sopenharmony_ci  BasicValueConverter() = default;
1676d528ed9Sopenharmony_ci
1686d528ed9Sopenharmony_ci  bool Convert(const base::Value& value, std::u16string* field) const override;
1696d528ed9Sopenharmony_ci
1706d528ed9Sopenharmony_ci private:
1716d528ed9Sopenharmony_ci  BasicValueConverter(const BasicValueConverter&) = delete;
1726d528ed9Sopenharmony_ci  BasicValueConverter& operator=(const BasicValueConverter&) = delete;
1736d528ed9Sopenharmony_ci};
1746d528ed9Sopenharmony_ci
1756d528ed9Sopenharmony_citemplate <>
1766d528ed9Sopenharmony_ciclass BasicValueConverter<double> : public ValueConverter<double> {
1776d528ed9Sopenharmony_ci public:
1786d528ed9Sopenharmony_ci  BasicValueConverter() = default;
1796d528ed9Sopenharmony_ci
1806d528ed9Sopenharmony_ci  bool Convert(const base::Value& value, double* field) const override;
1816d528ed9Sopenharmony_ci
1826d528ed9Sopenharmony_ci private:
1836d528ed9Sopenharmony_ci  BasicValueConverter(const BasicValueConverter&) = delete;
1846d528ed9Sopenharmony_ci  BasicValueConverter& operator=(const BasicValueConverter&) = delete;
1856d528ed9Sopenharmony_ci};
1866d528ed9Sopenharmony_ci
1876d528ed9Sopenharmony_citemplate <>
1886d528ed9Sopenharmony_ciclass BasicValueConverter<bool> : public ValueConverter<bool> {
1896d528ed9Sopenharmony_ci public:
1906d528ed9Sopenharmony_ci  BasicValueConverter() = default;
1916d528ed9Sopenharmony_ci
1926d528ed9Sopenharmony_ci  bool Convert(const base::Value& value, bool* field) const override;
1936d528ed9Sopenharmony_ci
1946d528ed9Sopenharmony_ci private:
1956d528ed9Sopenharmony_ci  BasicValueConverter(const BasicValueConverter&) = delete;
1966d528ed9Sopenharmony_ci  BasicValueConverter& operator=(const BasicValueConverter&) = delete;
1976d528ed9Sopenharmony_ci};
1986d528ed9Sopenharmony_ci
1996d528ed9Sopenharmony_citemplate <typename FieldType>
2006d528ed9Sopenharmony_ciclass ValueFieldConverter : public ValueConverter<FieldType> {
2016d528ed9Sopenharmony_ci public:
2026d528ed9Sopenharmony_ci  typedef bool (*ConvertFunc)(const base::Value* value, FieldType* field);
2036d528ed9Sopenharmony_ci
2046d528ed9Sopenharmony_ci  explicit ValueFieldConverter(ConvertFunc convert_func)
2056d528ed9Sopenharmony_ci      : convert_func_(convert_func) {}
2066d528ed9Sopenharmony_ci
2076d528ed9Sopenharmony_ci  bool Convert(const base::Value& value, FieldType* field) const override {
2086d528ed9Sopenharmony_ci    return convert_func_(&value, field);
2096d528ed9Sopenharmony_ci  }
2106d528ed9Sopenharmony_ci
2116d528ed9Sopenharmony_ci private:
2126d528ed9Sopenharmony_ci  ConvertFunc convert_func_;
2136d528ed9Sopenharmony_ci
2146d528ed9Sopenharmony_ci  ValueFieldConverter(const ValueFieldConverter&) = delete;
2156d528ed9Sopenharmony_ci  ValueFieldConverter& operator=(const ValueFieldConverter&) = delete;
2166d528ed9Sopenharmony_ci};
2176d528ed9Sopenharmony_ci
2186d528ed9Sopenharmony_citemplate <typename FieldType>
2196d528ed9Sopenharmony_ciclass CustomFieldConverter : public ValueConverter<FieldType> {
2206d528ed9Sopenharmony_ci public:
2216d528ed9Sopenharmony_ci  typedef bool (*ConvertFunc)(std::string_view value, FieldType* field);
2226d528ed9Sopenharmony_ci
2236d528ed9Sopenharmony_ci  explicit CustomFieldConverter(ConvertFunc convert_func)
2246d528ed9Sopenharmony_ci      : convert_func_(convert_func) {}
2256d528ed9Sopenharmony_ci
2266d528ed9Sopenharmony_ci  bool Convert(const base::Value& value, FieldType* field) const override {
2276d528ed9Sopenharmony_ci    std::string string_value;
2286d528ed9Sopenharmony_ci    return value.GetAsString(&string_value) &&
2296d528ed9Sopenharmony_ci           convert_func_(string_value, field);
2306d528ed9Sopenharmony_ci  }
2316d528ed9Sopenharmony_ci
2326d528ed9Sopenharmony_ci private:
2336d528ed9Sopenharmony_ci  ConvertFunc convert_func_;
2346d528ed9Sopenharmony_ci
2356d528ed9Sopenharmony_ci  CustomFieldConverter(const CustomFieldConverter&) = delete;
2366d528ed9Sopenharmony_ci  CustomFieldConverter& operator=(const CustomFieldConverter&) = delete;
2376d528ed9Sopenharmony_ci};
2386d528ed9Sopenharmony_ci
2396d528ed9Sopenharmony_citemplate <typename NestedType>
2406d528ed9Sopenharmony_ciclass NestedValueConverter : public ValueConverter<NestedType> {
2416d528ed9Sopenharmony_ci public:
2426d528ed9Sopenharmony_ci  NestedValueConverter() = default;
2436d528ed9Sopenharmony_ci
2446d528ed9Sopenharmony_ci  bool Convert(const base::Value& value, NestedType* field) const override {
2456d528ed9Sopenharmony_ci    return converter_.Convert(value, field);
2466d528ed9Sopenharmony_ci  }
2476d528ed9Sopenharmony_ci
2486d528ed9Sopenharmony_ci private:
2496d528ed9Sopenharmony_ci  JSONValueConverter<NestedType> converter_;
2506d528ed9Sopenharmony_ci  NestedValueConverter(const NestedValueConverter&) = delete;
2516d528ed9Sopenharmony_ci  NestedValueConverter& operator=(const NestedValueConverter&) = delete;
2526d528ed9Sopenharmony_ci};
2536d528ed9Sopenharmony_ci
2546d528ed9Sopenharmony_citemplate <typename Element>
2556d528ed9Sopenharmony_ciclass RepeatedValueConverter
2566d528ed9Sopenharmony_ci    : public ValueConverter<std::vector<std::unique_ptr<Element>>> {
2576d528ed9Sopenharmony_ci public:
2586d528ed9Sopenharmony_ci  RepeatedValueConverter() = default;
2596d528ed9Sopenharmony_ci
2606d528ed9Sopenharmony_ci  bool Convert(const base::Value& value,
2616d528ed9Sopenharmony_ci               std::vector<std::unique_ptr<Element>>* field) const override {
2626d528ed9Sopenharmony_ci    const base::ListValue* list = NULL;
2636d528ed9Sopenharmony_ci    if (!value.GetAsList(&list)) {
2646d528ed9Sopenharmony_ci      // The field is not a list.
2656d528ed9Sopenharmony_ci      return false;
2666d528ed9Sopenharmony_ci    }
2676d528ed9Sopenharmony_ci
2686d528ed9Sopenharmony_ci    field->reserve(list->GetSize());
2696d528ed9Sopenharmony_ci    for (size_t i = 0; i < list->GetSize(); ++i) {
2706d528ed9Sopenharmony_ci      const base::Value* element = NULL;
2716d528ed9Sopenharmony_ci      if (!list->Get(i, &element))
2726d528ed9Sopenharmony_ci        continue;
2736d528ed9Sopenharmony_ci
2746d528ed9Sopenharmony_ci      std::unique_ptr<Element> e(new Element);
2756d528ed9Sopenharmony_ci      if (basic_converter_.Convert(*element, e.get())) {
2766d528ed9Sopenharmony_ci        field->push_back(std::move(e));
2776d528ed9Sopenharmony_ci      } else {
2786d528ed9Sopenharmony_ci        return false;
2796d528ed9Sopenharmony_ci      }
2806d528ed9Sopenharmony_ci    }
2816d528ed9Sopenharmony_ci    return true;
2826d528ed9Sopenharmony_ci  }
2836d528ed9Sopenharmony_ci
2846d528ed9Sopenharmony_ci private:
2856d528ed9Sopenharmony_ci  BasicValueConverter<Element> basic_converter_;
2866d528ed9Sopenharmony_ci  RepeatedValueConverter(const RepeatedValueConverter&) = delete;
2876d528ed9Sopenharmony_ci  RepeatedValueConverter& operator=(const RepeatedValueConverter&) = delete;
2886d528ed9Sopenharmony_ci};
2896d528ed9Sopenharmony_ci
2906d528ed9Sopenharmony_citemplate <typename NestedType>
2916d528ed9Sopenharmony_ciclass RepeatedMessageConverter
2926d528ed9Sopenharmony_ci    : public ValueConverter<std::vector<std::unique_ptr<NestedType>>> {
2936d528ed9Sopenharmony_ci public:
2946d528ed9Sopenharmony_ci  RepeatedMessageConverter() = default;
2956d528ed9Sopenharmony_ci
2966d528ed9Sopenharmony_ci  bool Convert(const base::Value& value,
2976d528ed9Sopenharmony_ci               std::vector<std::unique_ptr<NestedType>>* field) const override {
2986d528ed9Sopenharmony_ci    const base::ListValue* list = NULL;
2996d528ed9Sopenharmony_ci    if (!value.GetAsList(&list))
3006d528ed9Sopenharmony_ci      return false;
3016d528ed9Sopenharmony_ci
3026d528ed9Sopenharmony_ci    field->reserve(list->GetSize());
3036d528ed9Sopenharmony_ci    for (size_t i = 0; i < list->GetSize(); ++i) {
3046d528ed9Sopenharmony_ci      const base::Value* element = NULL;
3056d528ed9Sopenharmony_ci      if (!list->Get(i, &element))
3066d528ed9Sopenharmony_ci        continue;
3076d528ed9Sopenharmony_ci
3086d528ed9Sopenharmony_ci      std::unique_ptr<NestedType> nested(new NestedType);
3096d528ed9Sopenharmony_ci      if (converter_.Convert(*element, nested.get())) {
3106d528ed9Sopenharmony_ci        field->push_back(std::move(nested));
3116d528ed9Sopenharmony_ci      } else {
3126d528ed9Sopenharmony_ci        return false;
3136d528ed9Sopenharmony_ci      }
3146d528ed9Sopenharmony_ci    }
3156d528ed9Sopenharmony_ci    return true;
3166d528ed9Sopenharmony_ci  }
3176d528ed9Sopenharmony_ci
3186d528ed9Sopenharmony_ci private:
3196d528ed9Sopenharmony_ci  JSONValueConverter<NestedType> converter_;
3206d528ed9Sopenharmony_ci  RepeatedMessageConverter(const RepeatedMessageConverter&) = delete;
3216d528ed9Sopenharmony_ci  RepeatedMessageConverter& operator=(const RepeatedMessageConverter&) = delete;
3226d528ed9Sopenharmony_ci};
3236d528ed9Sopenharmony_ci
3246d528ed9Sopenharmony_citemplate <typename NestedType>
3256d528ed9Sopenharmony_ciclass RepeatedCustomValueConverter
3266d528ed9Sopenharmony_ci    : public ValueConverter<std::vector<std::unique_ptr<NestedType>>> {
3276d528ed9Sopenharmony_ci public:
3286d528ed9Sopenharmony_ci  typedef bool (*ConvertFunc)(const base::Value* value, NestedType* field);
3296d528ed9Sopenharmony_ci
3306d528ed9Sopenharmony_ci  explicit RepeatedCustomValueConverter(ConvertFunc convert_func)
3316d528ed9Sopenharmony_ci      : convert_func_(convert_func) {}
3326d528ed9Sopenharmony_ci
3336d528ed9Sopenharmony_ci  bool Convert(const base::Value& value,
3346d528ed9Sopenharmony_ci               std::vector<std::unique_ptr<NestedType>>* field) const override {
3356d528ed9Sopenharmony_ci    const base::ListValue* list = NULL;
3366d528ed9Sopenharmony_ci    if (!value.GetAsList(&list))
3376d528ed9Sopenharmony_ci      return false;
3386d528ed9Sopenharmony_ci
3396d528ed9Sopenharmony_ci    field->reserve(list->GetSize());
3406d528ed9Sopenharmony_ci    for (size_t i = 0; i < list->GetSize(); ++i) {
3416d528ed9Sopenharmony_ci      const base::Value* element = NULL;
3426d528ed9Sopenharmony_ci      if (!list->Get(i, &element))
3436d528ed9Sopenharmony_ci        continue;
3446d528ed9Sopenharmony_ci
3456d528ed9Sopenharmony_ci      std::unique_ptr<NestedType> nested(new NestedType);
3466d528ed9Sopenharmony_ci      if ((*convert_func_)(element, nested.get())) {
3476d528ed9Sopenharmony_ci        field->push_back(std::move(nested));
3486d528ed9Sopenharmony_ci      } else {
3496d528ed9Sopenharmony_ci        return false;
3506d528ed9Sopenharmony_ci      }
3516d528ed9Sopenharmony_ci    }
3526d528ed9Sopenharmony_ci    return true;
3536d528ed9Sopenharmony_ci  }
3546d528ed9Sopenharmony_ci
3556d528ed9Sopenharmony_ci private:
3566d528ed9Sopenharmony_ci  ConvertFunc convert_func_;
3576d528ed9Sopenharmony_ci  RepeatedCustomValueConverter(const RepeatedCustomValueConverter&) = delete;
3586d528ed9Sopenharmony_ci  RepeatedCustomValueConverter& operator=(const RepeatedCustomValueConverter&) =
3596d528ed9Sopenharmony_ci      delete;
3606d528ed9Sopenharmony_ci};
3616d528ed9Sopenharmony_ci
3626d528ed9Sopenharmony_ci}  // namespace internal
3636d528ed9Sopenharmony_ci
3646d528ed9Sopenharmony_citemplate <class StructType>
3656d528ed9Sopenharmony_ciclass JSONValueConverter {
3666d528ed9Sopenharmony_ci public:
3676d528ed9Sopenharmony_ci  JSONValueConverter() { StructType::RegisterJSONConverter(this); }
3686d528ed9Sopenharmony_ci
3696d528ed9Sopenharmony_ci  void RegisterIntField(const std::string& field_name, int StructType::*field) {
3706d528ed9Sopenharmony_ci    fields_.push_back(
3716d528ed9Sopenharmony_ci        std::make_unique<internal::FieldConverter<StructType, int>>(
3726d528ed9Sopenharmony_ci            field_name, field, new internal::BasicValueConverter<int>));
3736d528ed9Sopenharmony_ci  }
3746d528ed9Sopenharmony_ci
3756d528ed9Sopenharmony_ci  void RegisterStringField(const std::string& field_name,
3766d528ed9Sopenharmony_ci                           std::string StructType::*field) {
3776d528ed9Sopenharmony_ci    fields_.push_back(
3786d528ed9Sopenharmony_ci        std::make_unique<internal::FieldConverter<StructType, std::string>>(
3796d528ed9Sopenharmony_ci            field_name, field, new internal::BasicValueConverter<std::string>));
3806d528ed9Sopenharmony_ci  }
3816d528ed9Sopenharmony_ci
3826d528ed9Sopenharmony_ci  void RegisterStringField(const std::string& field_name,
3836d528ed9Sopenharmony_ci                           std::u16string StructType::*field) {
3846d528ed9Sopenharmony_ci    fields_.push_back(
3856d528ed9Sopenharmony_ci        std::make_unique<internal::FieldConverter<StructType, std::u16string>>(
3866d528ed9Sopenharmony_ci            field_name, field,
3876d528ed9Sopenharmony_ci            new internal::BasicValueConverter<std::u16string>));
3886d528ed9Sopenharmony_ci  }
3896d528ed9Sopenharmony_ci
3906d528ed9Sopenharmony_ci  void RegisterBoolField(const std::string& field_name,
3916d528ed9Sopenharmony_ci                         bool StructType::*field) {
3926d528ed9Sopenharmony_ci    fields_.push_back(
3936d528ed9Sopenharmony_ci        std::make_unique<internal::FieldConverter<StructType, bool>>(
3946d528ed9Sopenharmony_ci            field_name, field, new internal::BasicValueConverter<bool>));
3956d528ed9Sopenharmony_ci  }
3966d528ed9Sopenharmony_ci
3976d528ed9Sopenharmony_ci  void RegisterDoubleField(const std::string& field_name,
3986d528ed9Sopenharmony_ci                           double StructType::*field) {
3996d528ed9Sopenharmony_ci    fields_.push_back(
4006d528ed9Sopenharmony_ci        std::make_unique<internal::FieldConverter<StructType, double>>(
4016d528ed9Sopenharmony_ci            field_name, field, new internal::BasicValueConverter<double>));
4026d528ed9Sopenharmony_ci  }
4036d528ed9Sopenharmony_ci
4046d528ed9Sopenharmony_ci  template <class NestedType>
4056d528ed9Sopenharmony_ci  void RegisterNestedField(const std::string& field_name,
4066d528ed9Sopenharmony_ci                           NestedType StructType::*field) {
4076d528ed9Sopenharmony_ci    fields_.push_back(
4086d528ed9Sopenharmony_ci        std::make_unique<internal::FieldConverter<StructType, NestedType>>(
4096d528ed9Sopenharmony_ci            field_name, field, new internal::NestedValueConverter<NestedType>));
4106d528ed9Sopenharmony_ci  }
4116d528ed9Sopenharmony_ci
4126d528ed9Sopenharmony_ci  template <typename FieldType>
4136d528ed9Sopenharmony_ci  void RegisterCustomField(const std::string& field_name,
4146d528ed9Sopenharmony_ci                           FieldType StructType::*field,
4156d528ed9Sopenharmony_ci                           bool (*convert_func)(std::string_view, FieldType*)) {
4166d528ed9Sopenharmony_ci    fields_.push_back(
4176d528ed9Sopenharmony_ci        std::make_unique<internal::FieldConverter<StructType, FieldType>>(
4186d528ed9Sopenharmony_ci            field_name, field,
4196d528ed9Sopenharmony_ci            new internal::CustomFieldConverter<FieldType>(convert_func)));
4206d528ed9Sopenharmony_ci  }
4216d528ed9Sopenharmony_ci
4226d528ed9Sopenharmony_ci  template <typename FieldType>
4236d528ed9Sopenharmony_ci  void RegisterCustomValueField(const std::string& field_name,
4246d528ed9Sopenharmony_ci                                FieldType StructType::*field,
4256d528ed9Sopenharmony_ci                                bool (*convert_func)(const base::Value*,
4266d528ed9Sopenharmony_ci                                                     FieldType*)) {
4276d528ed9Sopenharmony_ci    fields_.push_back(
4286d528ed9Sopenharmony_ci        std::make_unique<internal::FieldConverter<StructType, FieldType>>(
4296d528ed9Sopenharmony_ci            field_name, field,
4306d528ed9Sopenharmony_ci            new internal::ValueFieldConverter<FieldType>(convert_func)));
4316d528ed9Sopenharmony_ci  }
4326d528ed9Sopenharmony_ci
4336d528ed9Sopenharmony_ci  void RegisterRepeatedInt(
4346d528ed9Sopenharmony_ci      const std::string& field_name,
4356d528ed9Sopenharmony_ci      std::vector<std::unique_ptr<int>> StructType::*field) {
4366d528ed9Sopenharmony_ci    fields_.push_back(std::make_unique<internal::FieldConverter<
4376d528ed9Sopenharmony_ci                          StructType, std::vector<std::unique_ptr<int>>>>(
4386d528ed9Sopenharmony_ci        field_name, field, new internal::RepeatedValueConverter<int>));
4396d528ed9Sopenharmony_ci  }
4406d528ed9Sopenharmony_ci
4416d528ed9Sopenharmony_ci  void RegisterRepeatedString(
4426d528ed9Sopenharmony_ci      const std::string& field_name,
4436d528ed9Sopenharmony_ci      std::vector<std::unique_ptr<std::string>> StructType::*field) {
4446d528ed9Sopenharmony_ci    fields_.push_back(
4456d528ed9Sopenharmony_ci        std::make_unique<internal::FieldConverter<
4466d528ed9Sopenharmony_ci            StructType, std::vector<std::unique_ptr<std::string>>>>(
4476d528ed9Sopenharmony_ci            field_name, field,
4486d528ed9Sopenharmony_ci            new internal::RepeatedValueConverter<std::string>));
4496d528ed9Sopenharmony_ci  }
4506d528ed9Sopenharmony_ci
4516d528ed9Sopenharmony_ci  void RegisterRepeatedString(
4526d528ed9Sopenharmony_ci      const std::string& field_name,
4536d528ed9Sopenharmony_ci      std::vector<std::unique_ptr<std::u16string>> StructType::*field) {
4546d528ed9Sopenharmony_ci    fields_.push_back(
4556d528ed9Sopenharmony_ci        std::make_unique<internal::FieldConverter<
4566d528ed9Sopenharmony_ci            StructType, std::vector<std::unique_ptr<std::u16string>>>>(
4576d528ed9Sopenharmony_ci            field_name, field,
4586d528ed9Sopenharmony_ci            new internal::RepeatedValueConverter<std::u16string>));
4596d528ed9Sopenharmony_ci  }
4606d528ed9Sopenharmony_ci
4616d528ed9Sopenharmony_ci  void RegisterRepeatedDouble(
4626d528ed9Sopenharmony_ci      const std::string& field_name,
4636d528ed9Sopenharmony_ci      std::vector<std::unique_ptr<double>> StructType::*field) {
4646d528ed9Sopenharmony_ci    fields_.push_back(std::make_unique<internal::FieldConverter<
4656d528ed9Sopenharmony_ci                          StructType, std::vector<std::unique_ptr<double>>>>(
4666d528ed9Sopenharmony_ci        field_name, field, new internal::RepeatedValueConverter<double>));
4676d528ed9Sopenharmony_ci  }
4686d528ed9Sopenharmony_ci
4696d528ed9Sopenharmony_ci  void RegisterRepeatedBool(
4706d528ed9Sopenharmony_ci      const std::string& field_name,
4716d528ed9Sopenharmony_ci      std::vector<std::unique_ptr<bool>> StructType::*field) {
4726d528ed9Sopenharmony_ci    fields_.push_back(std::make_unique<internal::FieldConverter<
4736d528ed9Sopenharmony_ci                          StructType, std::vector<std::unique_ptr<bool>>>>(
4746d528ed9Sopenharmony_ci        field_name, field, new internal::RepeatedValueConverter<bool>));
4756d528ed9Sopenharmony_ci  }
4766d528ed9Sopenharmony_ci
4776d528ed9Sopenharmony_ci  template <class NestedType>
4786d528ed9Sopenharmony_ci  void RegisterRepeatedCustomValue(
4796d528ed9Sopenharmony_ci      const std::string& field_name,
4806d528ed9Sopenharmony_ci      std::vector<std::unique_ptr<NestedType>> StructType::*field,
4816d528ed9Sopenharmony_ci      bool (*convert_func)(const base::Value*, NestedType*)) {
4826d528ed9Sopenharmony_ci    fields_.push_back(
4836d528ed9Sopenharmony_ci        std::make_unique<internal::FieldConverter<
4846d528ed9Sopenharmony_ci            StructType, std::vector<std::unique_ptr<NestedType>>>>(
4856d528ed9Sopenharmony_ci            field_name, field,
4866d528ed9Sopenharmony_ci            new internal::RepeatedCustomValueConverter<NestedType>(
4876d528ed9Sopenharmony_ci                convert_func)));
4886d528ed9Sopenharmony_ci  }
4896d528ed9Sopenharmony_ci
4906d528ed9Sopenharmony_ci  template <class NestedType>
4916d528ed9Sopenharmony_ci  void RegisterRepeatedMessage(
4926d528ed9Sopenharmony_ci      const std::string& field_name,
4936d528ed9Sopenharmony_ci      std::vector<std::unique_ptr<NestedType>> StructType::*field) {
4946d528ed9Sopenharmony_ci    fields_.push_back(
4956d528ed9Sopenharmony_ci        std::make_unique<internal::FieldConverter<
4966d528ed9Sopenharmony_ci            StructType, std::vector<std::unique_ptr<NestedType>>>>(
4976d528ed9Sopenharmony_ci            field_name, field,
4986d528ed9Sopenharmony_ci            new internal::RepeatedMessageConverter<NestedType>));
4996d528ed9Sopenharmony_ci  }
5006d528ed9Sopenharmony_ci
5016d528ed9Sopenharmony_ci  bool Convert(const base::Value& value, StructType* output) const {
5026d528ed9Sopenharmony_ci    const DictionaryValue* dictionary_value = NULL;
5036d528ed9Sopenharmony_ci    if (!value.GetAsDictionary(&dictionary_value))
5046d528ed9Sopenharmony_ci      return false;
5056d528ed9Sopenharmony_ci
5066d528ed9Sopenharmony_ci    for (size_t i = 0; i < fields_.size(); ++i) {
5076d528ed9Sopenharmony_ci      const internal::FieldConverterBase<StructType>* field_converter =
5086d528ed9Sopenharmony_ci          fields_[i].get();
5096d528ed9Sopenharmony_ci      const base::Value* field = NULL;
5106d528ed9Sopenharmony_ci      if (dictionary_value->Get(field_converter->field_path(), &field)) {
5116d528ed9Sopenharmony_ci        if (!field_converter->ConvertField(*field, output)) {
5126d528ed9Sopenharmony_ci          return false;
5136d528ed9Sopenharmony_ci        }
5146d528ed9Sopenharmony_ci      }
5156d528ed9Sopenharmony_ci    }
5166d528ed9Sopenharmony_ci    return true;
5176d528ed9Sopenharmony_ci  }
5186d528ed9Sopenharmony_ci
5196d528ed9Sopenharmony_ci private:
5206d528ed9Sopenharmony_ci  std::vector<std::unique_ptr<internal::FieldConverterBase<StructType>>>
5216d528ed9Sopenharmony_ci      fields_;
5226d528ed9Sopenharmony_ci
5236d528ed9Sopenharmony_ci  JSONValueConverter(const JSONValueConverter&) = delete;
5246d528ed9Sopenharmony_ci  JSONValueConverter& operator=(const JSONValueConverter&) = delete;
5256d528ed9Sopenharmony_ci};
5266d528ed9Sopenharmony_ci
5276d528ed9Sopenharmony_ci}  // namespace base
5286d528ed9Sopenharmony_ci
5296d528ed9Sopenharmony_ci#endif  // BASE_JSON_JSON_VALUE_CONVERTER_H_
530