argument_spec.h 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. // Copyright 2016 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef EXTENSIONS_RENDERER_BINDINGS_ARGUMENT_SPEC_H_
  5. #define EXTENSIONS_RENDERER_BINDINGS_ARGUMENT_SPEC_H_
  6. #include <map>
  7. #include <memory>
  8. #include <set>
  9. #include <string>
  10. #include <vector>
  11. #include "base/strings/string_piece.h"
  12. #include "third_party/abseil-cpp/absl/types/optional.h"
  13. #include "v8/include/v8.h"
  14. namespace base {
  15. class DictionaryValue;
  16. class Value;
  17. }
  18. namespace extensions {
  19. class APITypeReferenceMap;
  20. enum class ArgumentType {
  21. INTEGER,
  22. DOUBLE,
  23. BOOLEAN,
  24. STRING,
  25. OBJECT,
  26. LIST,
  27. BINARY,
  28. FUNCTION,
  29. ANY,
  30. REF,
  31. CHOICES,
  32. };
  33. // A description of a given Argument to an Extension.
  34. class ArgumentSpec {
  35. public:
  36. using PropertiesMap = std::map<std::string, std::unique_ptr<ArgumentSpec>>;
  37. // Reads the description from |value| and sets associated fields.
  38. // TODO(devlin): We should strongly think about generating these instead of
  39. // populating them at runtime.
  40. explicit ArgumentSpec(const base::Value& value);
  41. explicit ArgumentSpec(ArgumentType type);
  42. ArgumentSpec(const ArgumentSpec&) = delete;
  43. ArgumentSpec& operator=(const ArgumentSpec&) = delete;
  44. ~ArgumentSpec();
  45. // Returns true if the given |value| is of the correct type to match this
  46. // spec. If it is not, populates |error|.
  47. bool IsCorrectType(v8::Local<v8::Value> value,
  48. const APITypeReferenceMap& refs,
  49. std::string* error) const;
  50. // Returns true if the passed |value| matches this specification. If
  51. // |out_value| is non-null, converts the value to a base::Value and populates
  52. // |out_value|. Similarly, if |v8_out_value| is non-null, this will populate
  53. // |v8_out_value| with the parsed value. The advantage to duplicating the
  54. // parsed value into |v8_out_value| is that for defined objects, the result
  55. // will be a data object with no getters/setters, so clients don't need to
  56. // worry about re-checking the arguments. Note that this will *not* apply in
  57. // the case of ArgumentType::ANY, ArgumentType::BINARY, or
  58. // ArgumentType::FUNCTION, where we do not copy the (arbitrary) contents.
  59. // If both |out_value| and |v8_out_value| are null, no conversion is
  60. // performed.
  61. bool ParseArgument(v8::Local<v8::Context> context,
  62. v8::Local<v8::Value> value,
  63. const APITypeReferenceMap& refs,
  64. std::unique_ptr<base::Value>* out_value,
  65. v8::Local<v8::Value>* v8_out_value,
  66. std::string* error) const;
  67. // Returns a type name for this argument. Note: This should only be used to
  68. // surface errors to developers.
  69. const std::string& GetTypeName() const;
  70. const std::string& name() const { return name_; }
  71. bool optional() const { return optional_; }
  72. ArgumentType type() const { return type_; }
  73. const std::set<std::string>& enum_values() const { return enum_values_; }
  74. void set_name(base::StringPiece name) { name_ = std::string(name); }
  75. void set_optional(bool optional) { optional_ = optional; }
  76. void set_ref(base::StringPiece ref) { ref_ = std::string(ref); }
  77. void set_minimum(int minimum) { minimum_ = minimum; }
  78. void set_properties(PropertiesMap properties) {
  79. properties_ = std::move(properties);
  80. }
  81. void set_list_element_type(std::unique_ptr<ArgumentSpec> list_element_type) {
  82. list_element_type_ = std::move(list_element_type);
  83. }
  84. void set_choices(std::vector<std::unique_ptr<ArgumentSpec>> choices) {
  85. choices_ = std::move(choices);
  86. }
  87. void set_enum_values(std::set<std::string> enum_values) {
  88. enum_values_ = std::move(enum_values);
  89. }
  90. void set_additional_properties(
  91. std::unique_ptr<ArgumentSpec> additional_properties) {
  92. additional_properties_ = std::move(additional_properties);
  93. }
  94. void set_instance_of(std::string instance_of) {
  95. instance_of_ = std::move(instance_of);
  96. }
  97. void set_preserve_null(bool preserve_null) { preserve_null_ = preserve_null; }
  98. void set_serialize_function(bool serialize_function) {
  99. serialize_function_ = serialize_function;
  100. }
  101. private:
  102. // Initializes this object according to |type_string| and |dict|.
  103. void InitializeType(const base::DictionaryValue* dict);
  104. // Conversion functions. These should only be used if the spec is of the given
  105. // type (otherwise, they will DCHECK).
  106. bool ParseArgumentToFundamental(v8::Local<v8::Context> context,
  107. v8::Local<v8::Value> value,
  108. std::unique_ptr<base::Value>* out_value,
  109. v8::Local<v8::Value>* v8_out_value,
  110. std::string* error) const;
  111. bool ParseArgumentToObject(v8::Local<v8::Context> context,
  112. v8::Local<v8::Object> object,
  113. const APITypeReferenceMap& refs,
  114. std::unique_ptr<base::Value>* out_value,
  115. v8::Local<v8::Value>* v8_out_value,
  116. std::string* error) const;
  117. bool ParseArgumentToArray(v8::Local<v8::Context> context,
  118. v8::Local<v8::Array> value,
  119. const APITypeReferenceMap& refs,
  120. std::unique_ptr<base::Value>* out_value,
  121. v8::Local<v8::Value>* v8_out_value,
  122. std::string* error) const;
  123. bool ParseArgumentToAny(v8::Local<v8::Context> context,
  124. v8::Local<v8::Value> value,
  125. std::unique_ptr<base::Value>* out_value,
  126. v8::Local<v8::Value>* v8_out_value,
  127. std::string* error) const;
  128. bool ParseArgumentToFunction(v8::Local<v8::Context> context,
  129. v8::Local<v8::Value> value,
  130. std::unique_ptr<base::Value>* out_value,
  131. v8::Local<v8::Value>* v8_out_value,
  132. std::string* error) const;
  133. // Returns an error message indicating the type of |value| does not match the
  134. // expected type.
  135. std::string GetInvalidTypeError(v8::Local<v8::Value> value) const;
  136. // The name of the argument.
  137. std::string name_;
  138. // The type of the argument.
  139. ArgumentType type_ = ArgumentType::INTEGER;
  140. // A readable type name for this argument, lazily initialized.
  141. mutable std::string type_name_;
  142. // Whether or not the argument is required.
  143. bool optional_ = false;
  144. // Whether to preserve null properties found in objects.
  145. bool preserve_null_ = false;
  146. // Whether to serialize (by stringifying) a function argument. Only valid for
  147. // arguments of type FUNCTION.
  148. bool serialize_function_ = false;
  149. // The reference the argument points to, if any. Note that if this is set,
  150. // none of the following fields describing the argument will be.
  151. absl::optional<std::string> ref_;
  152. // The type of instance an object should be, if any. Only applicable for
  153. // ArgumentType::OBJECT. If specified, the argument must contain the instance
  154. // type in its prototype chain.
  155. absl::optional<std::string> instance_of_;
  156. // A minimum and maximum for integer and double values, if any.
  157. absl::optional<int> minimum_;
  158. absl::optional<int> maximum_;
  159. // A minimium length for strings or arrays.
  160. absl::optional<size_t> min_length_;
  161. // A maximum length for strings or arrays.
  162. absl::optional<size_t> max_length_;
  163. // A map of required properties; present only for objects. Note that any
  164. // properties *not* defined in this map will be dropped during conversion.
  165. std::map<std::string, std::unique_ptr<ArgumentSpec>> properties_;
  166. // The type of item that should be in the list; present only for lists.
  167. std::unique_ptr<ArgumentSpec> list_element_type_;
  168. // The different possible specs this argument can map to. Only populated for
  169. // arguments of type CHOICES.
  170. std::vector<std::unique_ptr<ArgumentSpec>> choices_;
  171. // The possible enum values, if defined for this argument.
  172. std::set<std::string> enum_values_;
  173. // The specification for 'additional properties'. This is used when we want
  174. // to allow the API to pass an object with arbitrary properties. Only
  175. // applicable for ArgumentType::OBJECT.
  176. std::unique_ptr<ArgumentSpec> additional_properties_;
  177. };
  178. } // namespace extensions
  179. #endif // EXTENSIONS_RENDERER_BINDINGS_ARGUMENT_SPEC_H_