15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef TOOLS_JSON_SCHEMA_COMPILER_UTIL_H__
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define TOOLS_JSON_SCHEMA_COMPILER_UTIL_H__
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/linked_ptr.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace json_schema_compiler {
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace util {
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Creates a new item at |out| from |from|[|index|]. These are used by template
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// specializations of |Get(Optional)ArrayFromList|.
21eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool GetItemFromList(const base::ListValue& from, int index, int* out);
22eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool GetItemFromList(const base::ListValue& from, int index, bool* out);
23eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool GetItemFromList(const base::ListValue& from, int index, double* out);
24eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool GetItemFromList(const base::ListValue& from, int index, std::string* out);
25eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool GetItemFromList(const base::ListValue& from,
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     int index,
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     linked_ptr<base::Value>* out);
28eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool GetItemFromList(const base::ListValue& from,
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     int index,
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     linked_ptr<base::DictionaryValue>* out);
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This template is used for types generated by tools/json_schema_compiler.
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<class T>
34eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool GetItemFromList(const base::ListValue& from,
35eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                     int index,
36eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                     linked_ptr<T>* out) {
37eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  const base::DictionaryValue* dict;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!from.GetDictionary(index, &dict))
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<T> obj(new T());
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!T::Populate(*dict, obj.get()))
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *out = linked_ptr<T>(obj.release());
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Populates |out| with |list|. Returns false if there is no list at the
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// specified key or if the list has anything other than |T|.
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class T>
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PopulateArrayFromList(
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const base::ListValue& list, std::vector<T>* out) {
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  out->clear();
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  T value;
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < list.GetSize(); ++i) {
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!GetItemFromList(list, i, &value))
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    out->push_back(value);
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Populates |out| with |from|.|name|. Returns false if there is no list at
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the specified key or if the list has anything other than |T|.
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class T>
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PopulateArrayFromDictionary(
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const base::DictionaryValue& from,
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& name,
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::vector<T>* out) {
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const base::ListValue* list = NULL;
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!from.GetListWithoutPathExpansion(name, &list))
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return PopulateArrayFromList(*list, out);
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Creates a new vector containing |list| at |out|. Returns
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// true on success or if there is nothing at the specified key. Returns false
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// if anything other than a list of |T| is at the specified key.
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class T>
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PopulateOptionalArrayFromList(
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const base::ListValue& list,
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<std::vector<T> >* out) {
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  out->reset(new std::vector<T>());
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  T value;
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < list.GetSize(); ++i) {
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!GetItemFromList(list, i, &value)) {
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      out->reset();
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (*out)->push_back(value);
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Creates a new vector containing |from|.|name| at |out|. Returns
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// true on success or if there is nothing at the specified key. Returns false
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// if anything other than a list of |T| is at the specified key.
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class T>
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PopulateOptionalArrayFromDictionary(
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const base::DictionaryValue& from,
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& name,
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<std::vector<T> >* out) {
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const base::ListValue* list = NULL;
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const base::Value* maybe_list = NULL;
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Since |name| is optional, its absence is acceptable. However, anything
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // other than a ListValue is not.
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!from.GetWithoutPathExpansion(name, &maybe_list))
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!maybe_list->IsType(base::Value::TYPE_LIST))
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    list = static_cast<const base::ListValue*>(maybe_list);
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return PopulateOptionalArrayFromList(*list, out);
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Appends a Value newly created from |from| to |out|. These used by template
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// specializations of |Set(Optional)ArrayToList|.
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AddItemToList(const int from, base::ListValue* out);
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AddItemToList(const bool from, base::ListValue* out);
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AddItemToList(const double from, base::ListValue* out);
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AddItemToList(const std::string& from, base::ListValue* out);
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AddItemToList(const linked_ptr<base::Value>& from,
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   base::ListValue* out);
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AddItemToList(const linked_ptr<base::DictionaryValue>& from,
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   base::ListValue* out);
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This template is used for types generated by tools/json_schema_compiler.
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<class T>
133eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid AddItemToList(const linked_ptr<T>& from, base::ListValue* out) {
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  out->Append(from->ToValue().release());
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Set |out| to the the contents of |from|. Requires GetItemFromList to be
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// implemented for |T|.
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class T>
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PopulateListFromArray(
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::vector<T>& from,
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::ListValue* out) {
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  out->Clear();
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (typename std::vector<T>::const_iterator it = from.begin();
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      it != from.end(); ++it) {
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddItemToList(*it, out);
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Set |out| to the the contents of |from| if |from| is non-NULL. Requires
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// GetItemFromList to be implemented for |T|.
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class T>
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PopulateListFromOptionalArray(
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const scoped_ptr<std::vector<T> >& from,
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::ListValue* out) {
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (from.get())
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PopulateListFromArray(*from, out);
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class T>
162eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochscoped_ptr<base::Value> CreateValueFromArray(const std::vector<T>& from) {
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::ListValue* list = new base::ListValue();
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PopulateListFromArray(from, list);
165eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return scoped_ptr<base::Value>(list);
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class T>
169eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochscoped_ptr<base::Value> CreateValueFromOptionalArray(
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const scoped_ptr<std::vector<T> >& from) {
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (from.get())
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return CreateValueFromArray(*from);
173eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return scoped_ptr<base::Value>();
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)std::string ValueTypeToString(base::Value::Type type);
177c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace util
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace json_schema_compiler
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // TOOLS_JSON_SCHEMA_COMPILER_UTIL_H__
182