summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorreillyg <reillyg@chromium.org>2015-05-05 19:34:27 -0700
committerCommit bot <commit-bot@chromium.org>2015-05-06 02:35:09 +0000
commit89a17f7839bfedeee84ae1dbc178fb13dfe03eba (patch)
treeb82af8b83a26b7d0894a97fe5da2758ce4a014c0
parent123d3e51878397d4a001530cfb5279bbd506bf7c (diff)
downloadchromium_src-89a17f7839bfedeee84ae1dbc178fb13dfe03eba.zip
chromium_src-89a17f7839bfedeee84ae1dbc178fb13dfe03eba.tar.gz
chromium_src-89a17f7839bfedeee84ae1dbc178fb13dfe03eba.tar.bz2
Add support for passing errors through PopulateArrayFromList.
When a JSON schema includes an array of objects PopulateArrayFromList calls a specialized PopulateItem instance for the generated object type. When compiled with generate_error_messages=True the generated type's Populate method expects to receive an error parameter. This patch adds versions of the PopulateArrayFromList and PopulateItem functions that pass through and provide that parameter. This capability is required for a new manifest key that will include an array of objects being added as part of issue 468955. Review URL: https://codereview.chromium.org/1128523003 Cr-Commit-Position: refs/heads/master@{#328471}
-rw-r--r--tools/json_schema_compiler/cc_generator.py7
-rw-r--r--tools/json_schema_compiler/test/error_generation_unittest.cc6
-rw-r--r--tools/json_schema_compiler/util.cc90
-rw-r--r--tools/json_schema_compiler/util.h62
-rw-r--r--tools/json_schema_compiler/util_cc_helper.py12
5 files changed, 162 insertions, 15 deletions
diff --git a/tools/json_schema_compiler/cc_generator.py b/tools/json_schema_compiler/cc_generator.py
index 6faac39..4fa55be 100644
--- a/tools/json_schema_compiler/cc_generator.py
+++ b/tools/json_schema_compiler/cc_generator.py
@@ -778,10 +778,9 @@ class _Generator(object):
failure_value,
is_ptr=is_ptr))
else:
- c.Sblock('if (!%s) {' % self._util_cc_helper.PopulateArrayFromList(
- 'list',
- dst_var,
- is_ptr))
+ c.Sblock('if (!%s(%s)) {' % (
+ self._util_cc_helper.PopulateArrayFromListFunction(is_ptr),
+ self._GenerateArgs(('*list', '&%(dst_var)s'))))
c.Concat(self._GenerateError(
'"unable to populate array \'%%(parent_key)s\'"'))
if is_ptr and self._generate_error_messages:
diff --git a/tools/json_schema_compiler/test/error_generation_unittest.cc b/tools/json_schema_compiler/test/error_generation_unittest.cc
index 42f9576..904b6c9 100644
--- a/tools/json_schema_compiler/test/error_generation_unittest.cc
+++ b/tools/json_schema_compiler/test/error_generation_unittest.cc
@@ -170,7 +170,8 @@ TEST(JsonSchemaCompilerErrorTest, UnableToPopulateArray) {
scoped_ptr<base::ListValue> params_value = List(
new FundamentalValue(5),
new FundamentalValue(false));
- EXPECT_TRUE(EqualsUtf16("unable to populate array 'integers'",
+ EXPECT_TRUE(EqualsUtf16(
+ "expected integer, got boolean; unable to populate array 'integers'",
GetPopulateError<ChoiceType::Integers>(*params_value)));
}
}
@@ -294,7 +295,8 @@ TEST(JsonSchemaCompilerErrorTest, OptionalUnableToPopulateArray) {
base::string16 error;
EXPECT_TRUE(OptionalChoiceType::Integers::Populate(*params_value, &out,
&error));
- EXPECT_TRUE(EqualsUtf16("unable to populate array 'integers'",
+ EXPECT_TRUE(EqualsUtf16(
+ "expected integer, got boolean; unable to populate array 'integers'",
error));
EXPECT_EQ(NULL, out.as_integer.get());
}
diff --git a/tools/json_schema_compiler/util.cc b/tools/json_schema_compiler/util.cc
index 3e36cfc..b7c4ecc 100644
--- a/tools/json_schema_compiler/util.cc
+++ b/tools/json_schema_compiler/util.cc
@@ -5,6 +5,7 @@
#include "tools/json_schema_compiler/util.h"
#include "base/stl_util.h"
+#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
namespace json_schema_compiler {
@@ -14,18 +15,68 @@ bool PopulateItem(const base::Value& from, int* out) {
return from.GetAsInteger(out);
}
+bool PopulateItem(const base::Value& from, int* out, base::string16* error) {
+ if (!from.GetAsInteger(out)) {
+ if (error->length()) {
+ error->append(base::UTF8ToUTF16("; "));
+ }
+ error->append(base::UTF8ToUTF16("expected integer, got " +
+ ValueTypeToString(from.GetType())));
+ return false;
+ }
+ return true;
+}
+
bool PopulateItem(const base::Value& from, bool* out) {
return from.GetAsBoolean(out);
}
+bool PopulateItem(const base::Value& from, bool* out, base::string16* error) {
+ if (!from.GetAsBoolean(out)) {
+ if (error->length()) {
+ error->append(base::UTF8ToUTF16("; "));
+ }
+ error->append(base::UTF8ToUTF16("expected boolean, got " +
+ ValueTypeToString(from.GetType())));
+ return false;
+ }
+ return true;
+}
+
bool PopulateItem(const base::Value& from, double* out) {
return from.GetAsDouble(out);
}
+bool PopulateItem(const base::Value& from, double* out, base::string16* error) {
+ if (!from.GetAsDouble(out)) {
+ if (error->length()) {
+ error->append(base::UTF8ToUTF16("; "));
+ }
+ error->append(base::UTF8ToUTF16("expected double, got " +
+ ValueTypeToString(from.GetType())));
+ return false;
+ }
+ return true;
+}
+
bool PopulateItem(const base::Value& from, std::string* out) {
return from.GetAsString(out);
}
+bool PopulateItem(const base::Value& from,
+ std::string* out,
+ base::string16* error) {
+ if (!from.GetAsString(out)) {
+ if (error->length()) {
+ error->append(base::UTF8ToUTF16("; "));
+ }
+ error->append(base::UTF8ToUTF16("expected string, got " +
+ ValueTypeToString(from.GetType())));
+ return false;
+ }
+ return true;
+}
+
bool PopulateItem(const base::Value& from, std::vector<char>* out) {
const base::BinaryValue* binary = nullptr;
if (!from.GetAsBinary(&binary))
@@ -34,12 +85,35 @@ bool PopulateItem(const base::Value& from, std::vector<char>* out) {
return true;
}
+bool PopulateItem(const base::Value& from,
+ std::vector<char>* out,
+ base::string16* error) {
+ const base::BinaryValue* binary = nullptr;
+ if (!from.GetAsBinary(&binary)) {
+ if (error->length()) {
+ error->append(base::UTF8ToUTF16("; "));
+ }
+ error->append(base::UTF8ToUTF16("expected binary, got " +
+ ValueTypeToString(from.GetType())));
+ return false;
+ }
+ out->assign(binary->GetBuffer(), binary->GetBuffer() + binary->GetSize());
+ return true;
+}
+
bool PopulateItem(const base::Value& from, linked_ptr<base::Value>* out) {
*out = make_linked_ptr(from.DeepCopy());
return true;
}
bool PopulateItem(const base::Value& from,
+ linked_ptr<base::Value>* out,
+ base::string16* error) {
+ *out = make_linked_ptr(from.DeepCopy());
+ return true;
+}
+
+bool PopulateItem(const base::Value& from,
linked_ptr<base::DictionaryValue>* out) {
const base::DictionaryValue* dict = nullptr;
if (!from.GetAsDictionary(&dict))
@@ -48,6 +122,22 @@ bool PopulateItem(const base::Value& from,
return true;
}
+bool PopulateItem(const base::Value& from,
+ linked_ptr<base::DictionaryValue>* out,
+ base::string16* error) {
+ const base::DictionaryValue* dict = nullptr;
+ if (!from.GetAsDictionary(&dict)) {
+ if (error->length()) {
+ error->append(base::UTF8ToUTF16("; "));
+ }
+ error->append(base::UTF8ToUTF16("expected dictionary, got " +
+ ValueTypeToString(from.GetType())));
+ return false;
+ }
+ *out = make_linked_ptr(dict->DeepCopy());
+ return true;
+}
+
void AddItemToList(const int from, base::ListValue* out) {
out->Append(new base::FundamentalValue(from));
}
diff --git a/tools/json_schema_compiler/util.h b/tools/json_schema_compiler/util.h
index c27e48a..59d65d0 100644
--- a/tools/json_schema_compiler/util.h
+++ b/tools/json_schema_compiler/util.h
@@ -18,14 +18,31 @@ namespace util {
// Populates the item |out| from the value |from|. These are used by template
// specializations of |Get(Optional)ArrayFromList|.
+bool PopulateItem(const base::Value& from, linked_ptr<base::Value>* out);
+
bool PopulateItem(const base::Value& from, int* out);
+bool PopulateItem(const base::Value& from, int* out, base::string16* error);
bool PopulateItem(const base::Value& from, bool* out);
+bool PopulateItem(const base::Value& from, bool* out, base::string16* error);
bool PopulateItem(const base::Value& from, double* out);
+bool PopulateItem(const base::Value& from, double* out, base::string16* error);
bool PopulateItem(const base::Value& from, std::string* out);
+bool PopulateItem(const base::Value& from,
+ std::string* out,
+ base::string16* error);
bool PopulateItem(const base::Value& from, std::vector<char>* out);
+bool PopulateItem(const base::Value& from,
+ std::vector<char>* out,
+ base::string16* error);
+bool PopulateItem(const base::Value& from,
+ linked_ptr<base::Value>* out,
+ base::string16* error);
bool PopulateItem(const base::Value& from, linked_ptr<base::Value>* out);
bool PopulateItem(const base::Value& from,
linked_ptr<base::DictionaryValue>* out);
+bool PopulateItem(const base::Value& from,
+ linked_ptr<base::DictionaryValue>* out,
+ base::string16* error);
// This template is used for types generated by tools/json_schema_compiler.
template <class T>
@@ -40,6 +57,22 @@ bool PopulateItem(const base::Value& from, linked_ptr<T>* out) {
return true;
}
+// This template is used for types generated by tools/json_schema_compiler with
+// error generation enabled.
+template <class T>
+bool PopulateItem(const base::Value& from,
+ linked_ptr<T>* out,
+ base::string16* error) {
+ const base::DictionaryValue* dict = nullptr;
+ if (!from.GetAsDictionary(&dict))
+ return false;
+ scoped_ptr<T> obj(new T());
+ if (!T::Populate(*dict, obj.get(), error))
+ return false;
+ *out = linked_ptr<T>(obj.release());
+ return true;
+}
+
// Populates |out| with |list|. Returns false if there is no list at the
// specified key or if the list has anything other than |T|.
template <class T>
@@ -55,6 +88,23 @@ bool PopulateArrayFromList(const base::ListValue& list, std::vector<T>* out) {
return true;
}
+// Populates |out| with |list|. Returns false and sets |error| if there is no
+// list at the specified key or if the list has anything other than |T|.
+template <class T>
+bool PopulateArrayFromList(const base::ListValue& list,
+ std::vector<T>* out,
+ base::string16* error) {
+ out->clear();
+ T item;
+ for (const base::Value* value : list) {
+ if (!PopulateItem(*value, &item, error))
+ return false;
+ out->push_back(item);
+ }
+
+ return true;
+}
+
// Creates a new vector containing |list| at |out|. Returns
// true on success or if there is nothing at the specified key. Returns false
// if anything other than a list of |T| is at the specified key.
@@ -69,6 +119,18 @@ bool PopulateOptionalArrayFromList(const base::ListValue& list,
return true;
}
+template <class T>
+bool PopulateOptionalArrayFromList(const base::ListValue& list,
+ scoped_ptr<std::vector<T>>* out,
+ base::string16* error) {
+ out->reset(new std::vector<T>());
+ if (!PopulateArrayFromList(list, out->get(), error)) {
+ out->reset();
+ return false;
+ }
+ return true;
+}
+
// Appends a Value newly created from |from| to |out|. These used by template
// specializations of |Set(Optional)ArrayToList|.
void AddItemToList(const int from, base::ListValue* out);
diff --git a/tools/json_schema_compiler/util_cc_helper.py b/tools/json_schema_compiler/util_cc_helper.py
index c3acd5f..d69122d 100644
--- a/tools/json_schema_compiler/util_cc_helper.py
+++ b/tools/json_schema_compiler/util_cc_helper.py
@@ -12,18 +12,12 @@ class UtilCCHelper(object):
def __init__(self, type_manager):
self._type_manager = type_manager
- def PopulateArrayFromList(self, src, dst, optional):
- """Generates code to get an array from src into dst.
-
- src: ListValue*
- dst: std::vector or scoped_ptr<std::vector>
+ def PopulateArrayFromListFunction(self, optional):
+ """Returns the function to turn a list into a vector.
"""
populate_list_fn = ('PopulateOptionalArrayFromList' if optional
else 'PopulateArrayFromList')
- return ('%s::%s(*%s, &%s)') % (_API_UTIL_NAMESPACE,
- populate_list_fn,
- src,
- dst)
+ return ('%s::%s') % (_API_UTIL_NAMESPACE, populate_list_fn)
def CreateValueFromArray(self, src, optional):
"""Generates code to create a scoped_pt<Value> from the array at src.