1 /** 2 * Copyright (c) 2022-2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 #ifndef PANDA_TOOLING_INSPECTOR_REMOTE_OBJECT_H 16 #define PANDA_TOOLING_INSPECTOR_REMOTE_OBJECT_H 17 18 #include "numeric_id.h" 19 20 #include <cstddef> 21 #include <cstdint> 22 #include <functional> 23 #include <optional> 24 #include <string> 25 #include <type_traits> 26 #include <utility> 27 #include <variant> 28 #include <vector> 29 30 namespace ark { 31 class JsonObjectBuilder; 32 } // namespace ark 33 34 namespace ark::tooling::inspector { 35 class PropertyDescriptor; 36 37 class RemoteObject { 38 public: Undefined()39 static RemoteObject Undefined() 40 { 41 return RemoteObject(); 42 } 43 Null()44 static RemoteObject Null() 45 { 46 return RemoteObject(nullptr); 47 } 48 Boolean(bool boolean)49 static RemoteObject Boolean(bool boolean) 50 { 51 return RemoteObject(boolean); 52 } 53 Number(int32_t number)54 static RemoteObject Number(int32_t number) 55 { 56 return RemoteObject(NumberT {number}); 57 } 58 59 template <typename T, std::enable_if_t<std::is_floating_point_v<T>, int> = 0> Number(T number)60 static RemoteObject Number(T number) 61 { 62 return RemoteObject(NumberT {number}); 63 } 64 65 template <typename T, 66 std::enable_if_t<std::is_integral_v<T> && std::is_signed_v<T> && sizeof(int32_t) < sizeof(T), int> = 0> 67 static RemoteObject Number(T number) 68 { 69 if (INT32_MIN <= number && number <= INT32_MAX) { 70 return RemoteObject(NumberT {static_cast<int32_t>(number)}); 71 } 72 if (number < 0) { 73 return RemoteObject(BigIntT {-1, -static_cast<uintmax_t>(number)}); 74 } 75 return RemoteObject(BigIntT {1, static_cast<uintmax_t>(number)}); 76 } 77 78 template <typename T, std::enable_if_t<std::is_unsigned_v<T> && sizeof(int32_t) <= sizeof(T), int> = 0> Number(T number)79 static RemoteObject Number(T number) 80 { 81 if (number <= INT32_MAX) { 82 return RemoteObject(NumberT {static_cast<int32_t>(number)}); 83 } 84 return RemoteObject(BigIntT {1, number}); 85 } 86 String(std::string string)87 static RemoteObject String(std::string string) 88 { 89 return RemoteObject(std::move(string)); 90 } 91 Symbol(std::string description)92 static RemoteObject Symbol(std::string description) 93 { 94 return RemoteObject(SymbolT {std::move(description)}); 95 } 96 97 static RemoteObject Object(std::string className, std::optional<RemoteObjectId> objectId = std::nullopt, 98 std::optional<std::string> description = std::nullopt) 99 { 100 return RemoteObject(ObjectT {std::move(className), objectId, std::move(description)}); 101 } 102 103 static RemoteObject Array(std::string className, size_t length, 104 std::optional<RemoteObjectId> objectId = std::nullopt) 105 { 106 return RemoteObject(ArrayT {std::move(className), objectId, length}); 107 } 108 109 static RemoteObject Function(std::string className, std::string name, size_t length, 110 std::optional<RemoteObjectId> objectId = std::nullopt) 111 { 112 return RemoteObject(FunctionT {std::move(className), objectId, std::move(name), length}); 113 } 114 115 std::optional<RemoteObjectId> GetObjectId() const; 116 117 void GeneratePreview(const std::vector<PropertyDescriptor> &properties) const; 118 119 std::function<void(JsonObjectBuilder &)> ToJson() const; 120 121 private: 122 using NumberT = std::variant<int32_t, double>; 123 struct BigIntT { 124 int8_t sign; 125 uintmax_t value; 126 }; 127 struct SymbolT { 128 std::string description; 129 }; 130 struct ObjectT { 131 std::string className; 132 std::optional<RemoteObjectId> objectId; 133 std::optional<std::string> description; 134 }; 135 struct ArrayT { 136 std::string className; 137 std::optional<RemoteObjectId> objectId; 138 size_t length; 139 }; 140 struct FunctionT { 141 std::string className; 142 std::optional<RemoteObjectId> objectId; 143 std::string name; 144 size_t length; 145 }; 146 147 using Value = std::variant<std::monostate, std::nullptr_t, bool, NumberT, BigIntT, std::string, SymbolT, ObjectT, 148 ArrayT, FunctionT>; 149 150 class Type { 151 friend class RemoteObject; 152 153 public: Accessor()154 static Type Accessor() 155 { 156 return Type("accessor"); 157 } 158 159 std::function<void(JsonObjectBuilder &)> ToJson() const; 160 161 private: type_(type)162 explicit Type(const char *type, const char *subtype = nullptr) : type_(type), subtype_(subtype) {} 163 164 const char *type_; 165 const char *subtype_; 166 }; 167 168 struct PreviewProperty { 169 std::string name; 170 Type type; 171 std::optional<std::string> value; 172 bool isEntry; 173 }; 174 175 template <typename... T> RemoteObject(T &&...value)176 explicit RemoteObject(T &&...value) : value_(std::forward<T>(value)...) 177 { 178 } 179 180 static std::string GetDescription(const BigIntT &bigint); 181 static std::string GetDescription(const ObjectT &object); 182 static std::string GetDescription(const ArrayT &array); 183 static std::string GetDescription(const FunctionT &function); 184 Type GetType() const; 185 std::function<void(JsonObjectBuilder &)> PreviewToJson() const; 186 187 Value value_; 188 mutable std::vector<PreviewProperty> preview_; 189 }; 190 } // namespace ark::tooling::inspector 191 192 #endif // PANDA_TOOLING_INSPECTOR_REMOTE_OBJECT_H 193