1 /*
2  * Copyright (c) 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 
16 #ifndef META_INTERFACE_IMETADATA_H
17 #define META_INTERFACE_IMETADATA_H
18 
19 #include <base/containers/array_view.h>
20 #include <base/containers/string_view.h>
21 #include <base/containers/vector.h>
22 #include <core/plugin/intf_interface.h>
23 
24 #include <meta/api/util.h>
25 #include <meta/base/namespace.h>
26 #include <meta/base/types.h>
27 #include <meta/interface/interface_macros.h>
28 #include <meta/interface/intf_callable.h>
29 #include <meta/interface/intf_container.h>
30 #include <meta/interface/intf_function.h>
31 #include <meta/interface/property/intf_property.h>
32 #include <meta/interface/static_object_metadata.h>
33 
34 META_BEGIN_NAMESPACE()
35 
36 META_REGISTER_INTERFACE(IMetadata, "5ad7917a-e744-48bb-b789-9446d3712cf9")
37 
38 class IMetadata;
39 
40 /**
41  * @brief The IMetadata interface defines a queryable metadata interface for retrieving object properties and functions.
42  */
43 class IMetadata : public CORE_NS::IInterface {
44     META_INTERFACE(CORE_NS::IInterface, IMetadata)
45 public:
46     virtual IContainer::Ptr GetPropertyContainer() = 0;
47     virtual IContainer::ConstPtr GetPropertyContainer() const = 0;
48     /**
49      * @brief Returns all available properties.
50      */
51     virtual BASE_NS::vector<IProperty::Ptr> GetAllProperties() = 0;
52     virtual BASE_NS::vector<IProperty::ConstPtr> GetAllProperties() const = 0;
53     /**
54      * @brief Returns all available functions.
55      */
56     virtual BASE_NS::vector<IFunction::Ptr> GetAllFunctions() = 0;
57     virtual BASE_NS::vector<IFunction::ConstPtr> GetAllFunctions() const = 0;
58     /**
59      * @brief Returns all available events.
60      */
61     virtual BASE_NS::vector<IEvent::Ptr> GetAllEvents() = 0;
62     virtual BASE_NS::vector<IEvent::ConstPtr> GetAllEvents() const = 0;
63 
64     /**
65      * @brief Returns the property with a given name.
66      * @param name Name of the property to retrieve.
67      * @return The property or nullptr if such property does not exist.
68      */
69     virtual IProperty::Ptr GetPropertyByName(BASE_NS::string_view name) = 0;
70     virtual IProperty::ConstPtr GetPropertyByName(BASE_NS::string_view name) const = 0;
71     /**
72      * @brief Returns the function with a given name
73      * @param name Name of the function to retrieve.
74      * @return The function or nullptr if such function does not exist.
75      */
76     virtual IFunction::Ptr GetFunctionByName(BASE_NS::string_view name) = 0;
77     virtual IFunction::ConstPtr GetFunctionByName(BASE_NS::string_view name) const = 0;
78     /**
79      * @brief Returns the event with a given name
80      * @param name Name of the event to retrieve.
81      * @return The event or nullptr if such event does not exist.
82      */
83     virtual IEvent::ConstPtr GetEventByName(BASE_NS::string_view name) const = 0;
84     virtual IEvent::Ptr GetEventByName(BASE_NS::string_view name) = 0;
85 
86     /*
87      * @brief Make Deep copy of the metadata
88      * Notice that the IFunctions cannot be used without re-attaching to object
89      */
90     virtual IMetadata::Ptr CloneMetadata() const = 0;
91 
92     /**
93      * @brief Add function to metadata
94      */
95     virtual void AddFunction(const IFunction::Ptr&) = 0;
96     /**
97      * @brief Remove function from metadata
98      */
99     virtual void RemoveFunction(const IFunction::Ptr&) = 0;
100 
101     /**
102      * @brief Add property to metadata
103      */
104     virtual void AddProperty(const IProperty::Ptr&) = 0;
105     /**
106      * @brief Remove property from metadata
107      */
108     virtual void RemoveProperty(const IProperty::Ptr&) = 0;
109 
110     /**
111      * @brief Add event to metadata
112      */
113     virtual void AddEvent(const IEvent::Ptr&) = 0;
114     /**
115      * @brief Remove event from metadata
116      */
117     virtual void RemoveEvent(const IEvent::Ptr&) = 0;
118 
119     /**
120      * @brief Set all properties (removes previous properties)
121      */
122     virtual void SetProperties(const BASE_NS::vector<IProperty::Ptr>&) = 0;
123 
124     /**
125      * @brief Merge given metadata to current one
126      */
127     virtual void Merge(const IMetadata::Ptr&) = 0;
128 
129     // templated helper for named property fetching. handles typing etc.
130     // returns null if not found or type is not matching.
131     template<typename ValueType>
GetPropertyByName(BASE_NS::string_view name)132     Property<ValueType> GetPropertyByName(BASE_NS::string_view name)
133     {
134         return GetPropertyByName(name);
135     }
136     template<typename ValueType>
GetPropertyByName(BASE_NS::string_view name)137     Property<const ValueType> GetPropertyByName(BASE_NS::string_view name) const
138     {
139         return GetPropertyByName(name);
140     }
141     template<typename ValueType>
GetArrayPropertyByName(BASE_NS::string_view name)142     ArrayProperty<ValueType> GetArrayPropertyByName(BASE_NS::string_view name)
143     {
144         return GetPropertyByName(name);
145     }
146     template<typename ValueType>
GetArrayPropertyByName(BASE_NS::string_view name)147     ArrayProperty<const ValueType> GetArrayPropertyByName(BASE_NS::string_view name) const
148     {
149         return GetPropertyByName(name);
150     }
151 };
152 
153 template<typename ValueType>
154 constexpr auto GetValue(const META_NS::IMetadata* meta, BASE_NS::string_view name, ValueType defaultValue = {}) noexcept
155 {
156     if (meta) {
157         if (auto property = meta->GetPropertyByName<ValueType>(name)) {
158             return GetValue(property, defaultValue);
159         }
160     }
161     return BASE_NS::move(defaultValue);
162 }
163 
164 template<typename ValueType, typename Interface,
165     typename = BASE_NS::enable_if_t<IsKindOfIInterface_v<BASE_NS::remove_const_t<Interface>*>>>
166 constexpr auto GetValue(
167     const BASE_NS::shared_ptr<Interface>& intf, BASE_NS::string_view name, ValueType defaultValue = {}) noexcept
168 {
169     return GetValue<ValueType>(interface_cast<IMetadata>(intf), name, defaultValue);
170 }
171 
172 template<typename ValueType, typename Interface,
173     typename = BASE_NS::enable_if_t<IsKindOfIInterface_v<BASE_NS::remove_const_t<Interface>*>>>
174 constexpr auto GetValue(
175     const BASE_NS::weak_ptr<Interface>& intf, BASE_NS::string_view name, ValueType defaultValue = {}) noexcept
176 {
177     return GetValue<ValueType>(interface_pointer_cast<IMetadata>(intf), name, defaultValue);
178 }
179 
180 template<typename ValueType>
SetValue(META_NS::IMetadata * meta,BASE_NS::string_view name,const ValueType & value)181 constexpr bool SetValue(META_NS::IMetadata* meta, BASE_NS::string_view name, const ValueType& value) noexcept
182 {
183     if (meta) {
184         if (auto property = meta->GetPropertyByName<ValueType>(name)) {
185             return SetValue(property, value);
186         }
187     }
188     return false;
189 }
190 
191 template<typename ValueType, typename Interface, typename = BASE_NS::enable_if_t<IsKindOfIInterface_v<Interface*>>>
SetValue(const BASE_NS::shared_ptr<Interface> & intf,BASE_NS::string_view name,const ValueType & value)192 constexpr auto SetValue(
193     const BASE_NS::shared_ptr<Interface>& intf, BASE_NS::string_view name, const ValueType& value) noexcept
194 {
195     return SetValue(interface_cast<IMetadata>(intf), name, value);
196 }
197 
198 template<typename ValueType, typename Interface, typename = BASE_NS::enable_if_t<IsKindOfIInterface_v<Interface*>>>
SetValue(const BASE_NS::weak_ptr<Interface> & intf,BASE_NS::string_view name,const ValueType & value)199 constexpr bool SetValue(
200     const BASE_NS::weak_ptr<Interface>& intf, BASE_NS::string_view name, const ValueType& value) noexcept
201 {
202     return SetValue(interface_pointer_cast<IMetadata>(intf), name, value);
203 }
204 
205 /**
206  * @brief Internal interface to set metadata for objects
207  */
208 class IMetadataInternal : public CORE_NS::IInterface {
209     META_INTERFACE(CORE_NS::IInterface, IMetadataInternal, "3e748485-88bd-4098-ae8d-cf5ada17461d")
210 public:
211     virtual IMetadata::Ptr GetMetadata() const = 0;
212     virtual void SetMetadata(const IMetadata::Ptr& meta) = 0;
213     virtual const StaticObjectMetadata& GetStaticMetadata() const = 0;
214 };
215 
216 META_END_NAMESPACE()
217 
218 META_INTERFACE_TYPE(META_NS::IMetadata);
219 
220 #endif
221