blob: 228316fe91a6b4754ebbd9c0bc7b1d13595cde3d [file] [log] [blame]
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -07001// Copyright 2014 The Chromium OS 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
5#ifndef BUFFET_COMMANDS_PROP_VALUES_H_
6#define BUFFET_COMMANDS_PROP_VALUES_H_
7
8#include <map>
9#include <memory>
10#include <string>
11
Alex Vakulenkoa6fb4ed2014-08-22 15:05:35 -070012#include <chromeos/any.h>
Alex Vakulenkoa8b95bc2014-08-27 11:00:57 -070013#include <chromeos/errors/error.h>
Alex Vakulenko5f472062014-08-14 17:54:04 -070014
Alex Vakulenko66ec2922014-06-17 15:30:22 -070015#include "buffet/commands/schema_utils.h"
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -070016
17namespace base {
18class Value;
19class DictionaryValue;
20} // namespace base
21
22namespace buffet {
23
24// Enumeration to indicate supported command parameter types.
25enum class ValueType {
26 Int,
27 Double,
28 String,
Alex Vakulenko66ec2922014-06-17 15:30:22 -070029 Boolean,
Alex Vakulenko29e64442015-03-20 13:59:19 -070030 Object,
31 Array,
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -070032};
33
Alex Vakulenko66ec2922014-06-17 15:30:22 -070034class PropValue;
35class IntValue;
36class DoubleValue;
37class StringValue;
38class BooleanValue;
39class ObjectValue;
Alex Vakulenko29e64442015-03-20 13:59:19 -070040class ArrayValue;
Alex Vakulenko66ec2922014-06-17 15:30:22 -070041
42class PropType;
43
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -070044// Helper methods to get the parameter type enum value for the given
45// native C++ data representation.
46// The generic GetValueType<T>() is undefined, however particular
47// type specializations return the appropriate ValueType.
48template<typename T> ValueType GetValueType(); // Undefined.
Alex Vakulenko66ec2922014-06-17 15:30:22 -070049template<>
50inline ValueType GetValueType<int>() { return ValueType::Int; }
51template<>
52inline ValueType GetValueType<double>() { return ValueType::Double; }
53template<>
54inline ValueType GetValueType<std::string>() { return ValueType::String; }
55template<>
56inline ValueType GetValueType<bool>() { return ValueType::Boolean; }
57template<>
58inline ValueType GetValueType<native_types::Object>() {
59 return ValueType::Object;
60}
Alex Vakulenko29e64442015-03-20 13:59:19 -070061template<>
62inline ValueType GetValueType<native_types::Array>() {
63 return ValueType::Array;
64}
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -070065
Alex Vakulenko66ec2922014-06-17 15:30:22 -070066// The base class for property values.
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -070067// Concrete value classes of various types will be derived from this base.
Alex Vakulenko66ec2922014-06-17 15:30:22 -070068// A property value is the actual command parameter value (or a concrete value
69// that can be used in constraints and presets). The PropValue is mostly
70// just parsed content of base::Value when a command is dispatched, however
71// it does have some additional functionality:
72// - it has a reference to the type definition (PropType) which is used
73// when validating the value, especially for "object" types.
74// - it can be compared with another instances of values of the same type.
75// This is used to validate the values against "enum"/"one of" constraints.
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -070076class PropValue {
77 public:
Alex Vakulenko5ef75792015-03-19 15:50:44 -070078 explicit PropValue(std::unique_ptr<const PropType> type);
79 // Special out-of-line constructor to help implement PropValue::Clone().
80 // That method needs to clone the underlying type but can't do this in this
81 // header file since PropType is just forward-declared (it needs PropValue
82 // fully defined in its own inner workings).
83 explicit PropValue(const PropType* type_ptr);
84 virtual ~PropValue();
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -070085
86 // Gets the type of the value.
87 virtual ValueType GetType() const = 0;
88
89 // Type conversion methods. Used in lieu of RTTI and dynamic_cast<>.
90 virtual IntValue* GetInt() { return nullptr; }
91 virtual IntValue const* GetInt() const { return nullptr; }
92 virtual DoubleValue* GetDouble() { return nullptr; }
93 virtual DoubleValue const* GetDouble() const { return nullptr; }
94 virtual StringValue* GetString() { return nullptr; }
95 virtual StringValue const* GetString() const { return nullptr; }
96 virtual BooleanValue* GetBoolean() { return nullptr; }
97 virtual BooleanValue const* GetBoolean() const { return nullptr; }
Alex Vakulenko66ec2922014-06-17 15:30:22 -070098 virtual ObjectValue* GetObject() { return nullptr; }
99 virtual ObjectValue const* GetObject() const { return nullptr; }
Alex Vakulenko29e64442015-03-20 13:59:19 -0700100 virtual ArrayValue* GetArray() { return nullptr; }
101 virtual ArrayValue const* GetArray() const { return nullptr; }
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700102
103 // Makes a full copy of this value class.
Alex Vakulenko5ef75792015-03-19 15:50:44 -0700104 virtual std::unique_ptr<PropValue> Clone() const = 0;
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700105
106 // Saves the value as a JSON object.
107 // If it fails, returns nullptr value and fills in the details for the
108 // failure in the |error| parameter.
Alex Vakulenko5f472062014-08-14 17:54:04 -0700109 virtual std::unique_ptr<base::Value> ToJson(
110 chromeos::ErrorPtr* error) const = 0;
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700111 // Parses a value from JSON.
112 // If it fails, it returns false and provides additional information
113 // via the |error| parameter.
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700114 virtual bool FromJson(const base::Value* value,
Alex Vakulenko5f472062014-08-14 17:54:04 -0700115 chromeos::ErrorPtr* error) = 0;
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700116
117 // Returns the contained C++ value as Any.
Alex Vakulenkoa6fb4ed2014-08-22 15:05:35 -0700118 virtual chromeos::Any GetValueAsAny() const = 0;
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700119
120 // Return the type definition of this value.
Alex Vakulenko5ef75792015-03-19 15:50:44 -0700121 const PropType* GetPropType() const { return type_.get(); }
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700122 // Compares two values and returns true if they are equal.
123 virtual bool IsEqual(const PropValue* value) const = 0;
124
125 protected:
Alex Vakulenko5ef75792015-03-19 15:50:44 -0700126 std::unique_ptr<const PropType> type_;
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700127};
128
Alex Vakulenko29e64442015-03-20 13:59:19 -0700129// A helper template base class for implementing value classes.
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700130template<typename Derived, typename T>
131class TypedValueBase : public PropValue {
132 public:
Alex Vakulenko29e64442015-03-20 13:59:19 -0700133 // To help refer to this base class from derived classes, define Base to
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700134 // be this class.
Alex Vakulenko29e64442015-03-20 13:59:19 -0700135 using Base = TypedValueBase<Derived, T>;
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700136 // Expose the non-default constructor of the base class.
137 using PropValue::PropValue;
138
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700139 // Overrides from PropValue base class.
Alex Vakulenko5a9e7182014-08-11 15:59:58 -0700140 ValueType GetType() const override { return GetValueType<T>(); }
Alex Vakulenko5ef75792015-03-19 15:50:44 -0700141
142 std::unique_ptr<PropValue> Clone() const override {
143 std::unique_ptr<Derived> derived{new Derived{type_.get()}};
144 derived->value_ = value_;
145 return std::move(derived);
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700146 }
147
Alex Vakulenko5f472062014-08-14 17:54:04 -0700148 std::unique_ptr<base::Value> ToJson(
149 chromeos::ErrorPtr* error) const override {
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700150 return TypedValueToJson(value_, error);
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700151 }
152
Alex Vakulenko5f472062014-08-14 17:54:04 -0700153 bool FromJson(const base::Value* value, chromeos::ErrorPtr* error) override {
Alex Vakulenkod94656e2015-03-18 09:54:37 -0700154 return TypedValueFromJson(value, GetPropType(), &value_, error);
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700155 }
156
Alex Vakulenko5a9e7182014-08-11 15:59:58 -0700157 bool IsEqual(const PropValue* value) const override {
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700158 if (GetType() != value->GetType())
159 return false;
Alex Vakulenko29e64442015-03-20 13:59:19 -0700160 const Base* value_base = static_cast<const Base*>(value);
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700161 return CompareValue(GetValue(), value_base->GetValue());
162 }
163
164 // Helper methods to get and set the C++ representation of the value.
Alex Vakulenkoa6fb4ed2014-08-22 15:05:35 -0700165 chromeos::Any GetValueAsAny() const override { return value_; }
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700166 const T& GetValue() const { return value_; }
167 void SetValue(T value) { value_ = std::move(value); }
168
169 protected:
170 T value_{}; // The value of the parameter in C++ data representation.
171};
172
173// Value of type Integer.
174class IntValue final : public TypedValueBase<IntValue, int> {
175 public:
Alex Vakulenko29e64442015-03-20 13:59:19 -0700176 using Base::Base; // Expose the custom constructor of the base class.
Alex Vakulenko5a9e7182014-08-11 15:59:58 -0700177 IntValue* GetInt() override { return this; }
178 IntValue const* GetInt() const override { return this; }
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700179};
180
181// Value of type Number.
182class DoubleValue final : public TypedValueBase<DoubleValue, double> {
183 public:
Alex Vakulenko29e64442015-03-20 13:59:19 -0700184 using Base::Base; // Expose the custom constructor of the base class.
Alex Vakulenko5a9e7182014-08-11 15:59:58 -0700185 DoubleValue* GetDouble() override { return this; }
186 DoubleValue const* GetDouble() const override { return this; }
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700187};
188
189// Value of type String.
190class StringValue final : public TypedValueBase<StringValue, std::string> {
191 public:
Alex Vakulenko29e64442015-03-20 13:59:19 -0700192 using Base::Base; // Expose the custom constructor of the base class.
Alex Vakulenko5a9e7182014-08-11 15:59:58 -0700193 StringValue* GetString() override { return this; }
194 StringValue const* GetString() const override { return this; }
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700195};
196
197// Value of type Boolean.
198class BooleanValue final : public TypedValueBase<BooleanValue, bool> {
199 public:
Alex Vakulenko29e64442015-03-20 13:59:19 -0700200 using Base::Base; // Expose the custom constructor of the base class.
Alex Vakulenko5a9e7182014-08-11 15:59:58 -0700201 BooleanValue* GetBoolean() override { return this; }
202 BooleanValue const* GetBoolean() const override { return this; }
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700203};
204
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700205// Value of type Object.
Alex Vakulenkod94656e2015-03-18 09:54:37 -0700206class ObjectValue final
207 : public TypedValueBase<ObjectValue, native_types::Object> {
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700208 public:
Alex Vakulenko29e64442015-03-20 13:59:19 -0700209 using Base::Base; // Expose the custom constructor of the base class.
Alex Vakulenko5a9e7182014-08-11 15:59:58 -0700210 ObjectValue* GetObject() override { return this; }
211 ObjectValue const* GetObject() const override { return this; }
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700212};
Alex Vakulenko29e64442015-03-20 13:59:19 -0700213
214// Value of type Array.
215class ArrayValue final
216 : public TypedValueBase<ArrayValue, native_types::Array> {
217 public:
218 using Base::Base; // Expose the custom constructor of the base class.
219 ArrayValue* GetArray() override { return this; }
220 ArrayValue const* GetArray() const override { return this; }
221};
222
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700223} // namespace buffet
224
225#endif // BUFFET_COMMANDS_PROP_VALUES_H_