blob: 6f85a0cade768bd7830a6e70c34215e6a5b1598f [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,
30 Object
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -070031};
32
Alex Vakulenko66ec2922014-06-17 15:30:22 -070033class PropValue;
34class IntValue;
35class DoubleValue;
36class StringValue;
37class BooleanValue;
38class ObjectValue;
39
40class PropType;
41
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -070042// Helper methods to get the parameter type enum value for the given
43// native C++ data representation.
44// The generic GetValueType<T>() is undefined, however particular
45// type specializations return the appropriate ValueType.
46template<typename T> ValueType GetValueType(); // Undefined.
Alex Vakulenko66ec2922014-06-17 15:30:22 -070047template<>
48inline ValueType GetValueType<int>() { return ValueType::Int; }
49template<>
50inline ValueType GetValueType<double>() { return ValueType::Double; }
51template<>
52inline ValueType GetValueType<std::string>() { return ValueType::String; }
53template<>
54inline ValueType GetValueType<bool>() { return ValueType::Boolean; }
55template<>
56inline ValueType GetValueType<native_types::Object>() {
57 return ValueType::Object;
58}
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -070059
Alex Vakulenko66ec2922014-06-17 15:30:22 -070060// The base class for property values.
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -070061// Concrete value classes of various types will be derived from this base.
Alex Vakulenko66ec2922014-06-17 15:30:22 -070062// A property value is the actual command parameter value (or a concrete value
63// that can be used in constraints and presets). The PropValue is mostly
64// just parsed content of base::Value when a command is dispatched, however
65// it does have some additional functionality:
66// - it has a reference to the type definition (PropType) which is used
67// when validating the value, especially for "object" types.
68// - it can be compared with another instances of values of the same type.
69// This is used to validate the values against "enum"/"one of" constraints.
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -070070class PropValue {
71 public:
Alex Vakulenko5ef75792015-03-19 15:50:44 -070072 explicit PropValue(std::unique_ptr<const PropType> type);
73 // Special out-of-line constructor to help implement PropValue::Clone().
74 // That method needs to clone the underlying type but can't do this in this
75 // header file since PropType is just forward-declared (it needs PropValue
76 // fully defined in its own inner workings).
77 explicit PropValue(const PropType* type_ptr);
78 virtual ~PropValue();
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -070079
80 // Gets the type of the value.
81 virtual ValueType GetType() const = 0;
82
83 // Type conversion methods. Used in lieu of RTTI and dynamic_cast<>.
84 virtual IntValue* GetInt() { return nullptr; }
85 virtual IntValue const* GetInt() const { return nullptr; }
86 virtual DoubleValue* GetDouble() { return nullptr; }
87 virtual DoubleValue const* GetDouble() const { return nullptr; }
88 virtual StringValue* GetString() { return nullptr; }
89 virtual StringValue const* GetString() const { return nullptr; }
90 virtual BooleanValue* GetBoolean() { return nullptr; }
91 virtual BooleanValue const* GetBoolean() const { return nullptr; }
Alex Vakulenko66ec2922014-06-17 15:30:22 -070092 virtual ObjectValue* GetObject() { return nullptr; }
93 virtual ObjectValue const* GetObject() const { return nullptr; }
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -070094
95 // Makes a full copy of this value class.
Alex Vakulenko5ef75792015-03-19 15:50:44 -070096 virtual std::unique_ptr<PropValue> Clone() const = 0;
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -070097
98 // Saves the value as a JSON object.
99 // If it fails, returns nullptr value and fills in the details for the
100 // failure in the |error| parameter.
Alex Vakulenko5f472062014-08-14 17:54:04 -0700101 virtual std::unique_ptr<base::Value> ToJson(
102 chromeos::ErrorPtr* error) const = 0;
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700103 // Parses a value from JSON.
104 // If it fails, it returns false and provides additional information
105 // via the |error| parameter.
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700106 virtual bool FromJson(const base::Value* value,
Alex Vakulenko5f472062014-08-14 17:54:04 -0700107 chromeos::ErrorPtr* error) = 0;
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700108
109 // Returns the contained C++ value as Any.
Alex Vakulenkoa6fb4ed2014-08-22 15:05:35 -0700110 virtual chromeos::Any GetValueAsAny() const = 0;
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700111
112 // Return the type definition of this value.
Alex Vakulenko5ef75792015-03-19 15:50:44 -0700113 const PropType* GetPropType() const { return type_.get(); }
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700114 // Compares two values and returns true if they are equal.
115 virtual bool IsEqual(const PropValue* value) const = 0;
116
117 protected:
Alex Vakulenko5ef75792015-03-19 15:50:44 -0700118 std::unique_ptr<const PropType> type_;
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700119};
120
121// A helper template base class for implementing simple (non-Object) value
122// classes.
123template<typename Derived, typename T>
124class TypedValueBase : public PropValue {
125 public:
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700126 // To help refer to this base class from derived classes, define _Base to
127 // be this class.
128 using _Base = TypedValueBase<Derived, T>;
129 // Expose the non-default constructor of the base class.
130 using PropValue::PropValue;
131
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700132 // Overrides from PropValue base class.
Alex Vakulenko5a9e7182014-08-11 15:59:58 -0700133 ValueType GetType() const override { return GetValueType<T>(); }
Alex Vakulenko5ef75792015-03-19 15:50:44 -0700134
135 std::unique_ptr<PropValue> Clone() const override {
136 std::unique_ptr<Derived> derived{new Derived{type_.get()}};
137 derived->value_ = value_;
138 return std::move(derived);
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700139 }
140
Alex Vakulenko5f472062014-08-14 17:54:04 -0700141 std::unique_ptr<base::Value> ToJson(
142 chromeos::ErrorPtr* error) const override {
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700143 return TypedValueToJson(value_, error);
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700144 }
145
Alex Vakulenko5f472062014-08-14 17:54:04 -0700146 bool FromJson(const base::Value* value, chromeos::ErrorPtr* error) override {
Alex Vakulenkod94656e2015-03-18 09:54:37 -0700147 return TypedValueFromJson(value, GetPropType(), &value_, error);
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700148 }
149
Alex Vakulenko5a9e7182014-08-11 15:59:58 -0700150 bool IsEqual(const PropValue* value) const override {
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700151 if (GetType() != value->GetType())
152 return false;
153 const _Base* value_base = static_cast<const _Base*>(value);
154 return CompareValue(GetValue(), value_base->GetValue());
155 }
156
157 // Helper methods to get and set the C++ representation of the value.
Alex Vakulenkoa6fb4ed2014-08-22 15:05:35 -0700158 chromeos::Any GetValueAsAny() const override { return value_; }
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700159 const T& GetValue() const { return value_; }
160 void SetValue(T value) { value_ = std::move(value); }
161
162 protected:
163 T value_{}; // The value of the parameter in C++ data representation.
164};
165
166// Value of type Integer.
167class IntValue final : public TypedValueBase<IntValue, int> {
168 public:
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700169 using _Base::_Base; // Expose the custom constructor of the base class.
Alex Vakulenko5a9e7182014-08-11 15:59:58 -0700170 IntValue* GetInt() override { return this; }
171 IntValue const* GetInt() const override { return this; }
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700172};
173
174// Value of type Number.
175class DoubleValue final : public TypedValueBase<DoubleValue, double> {
176 public:
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700177 using _Base::_Base; // Expose the custom constructor of the base class.
Alex Vakulenko5a9e7182014-08-11 15:59:58 -0700178 DoubleValue* GetDouble() override { return this; }
179 DoubleValue const* GetDouble() const override { return this; }
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700180};
181
182// Value of type String.
183class StringValue final : public TypedValueBase<StringValue, std::string> {
184 public:
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700185 using _Base::_Base; // Expose the custom constructor of the base class.
Alex Vakulenko5a9e7182014-08-11 15:59:58 -0700186 StringValue* GetString() override { return this; }
187 StringValue const* GetString() const override { return this; }
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700188};
189
190// Value of type Boolean.
191class BooleanValue final : public TypedValueBase<BooleanValue, bool> {
192 public:
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700193 using _Base::_Base; // Expose the custom constructor of the base class.
Alex Vakulenko5a9e7182014-08-11 15:59:58 -0700194 BooleanValue* GetBoolean() override { return this; }
195 BooleanValue const* GetBoolean() const override { return this; }
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700196};
197
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700198// Value of type Object.
Alex Vakulenkod94656e2015-03-18 09:54:37 -0700199class ObjectValue final
200 : public TypedValueBase<ObjectValue, native_types::Object> {
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700201 public:
202 using _Base::_Base; // Expose the custom constructor of the base class.
Alex Vakulenko5a9e7182014-08-11 15:59:58 -0700203 ObjectValue* GetObject() override { return this; }
204 ObjectValue const* GetObject() const override { return this; }
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700205};
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700206} // namespace buffet
207
208#endif // BUFFET_COMMANDS_PROP_VALUES_H_