1 //===-- OptionValueProperties.h ---------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef LLDB_INTERPRETER_OPTIONVALUEPROPERTIES_H
10 #define LLDB_INTERPRETER_OPTIONVALUEPROPERTIES_H
11 
12 #include <vector>
13 
14 #include "lldb/Core/FormatEntity.h"
15 #include "lldb/Core/UniqueCStringMap.h"
16 #include "lldb/Interpreter/OptionValue.h"
17 #include "lldb/Interpreter/Property.h"
18 
19 namespace lldb_private {
20 class Properties;
21 
22 class OptionValueProperties
23     : public Cloneable<OptionValueProperties, OptionValue>,
24       public std::enable_shared_from_this<OptionValueProperties> {
25 public:
26   OptionValueProperties() = default;
27 
28   OptionValueProperties(llvm::StringRef name);
29 
30   ~OptionValueProperties() override = default;
31 
32   Type GetType() const override { return eTypeProperties; }
33 
34   void Clear() override;
35 
36   static lldb::OptionValuePropertiesSP
37   CreateLocalCopy(const Properties &global_properties);
38 
39   lldb::OptionValueSP
40   DeepCopy(const lldb::OptionValueSP &new_parent) const override;
41 
42   Status
43   SetValueFromString(llvm::StringRef value,
44                      VarSetOperationType op = eVarSetOperationAssign) override;
45 
46   void DumpValue(const ExecutionContext *exe_ctx, Stream &strm,
47                  uint32_t dump_mask) override;
48 
49   llvm::json::Value ToJSON(const ExecutionContext *exe_ctx) override;
50 
51   llvm::StringRef GetName() const override { return m_name; }
52 
53   virtual Status DumpPropertyValue(const ExecutionContext *exe_ctx,
54                                    Stream &strm, llvm::StringRef property_path,
55                                    uint32_t dump_mask, bool is_json = false);
56 
57   virtual void DumpAllDescriptions(CommandInterpreter &interpreter,
58                                    Stream &strm) const;
59 
60   void Apropos(llvm::StringRef keyword,
61                std::vector<const Property *> &matching_properties) const;
62 
63   void Initialize(const PropertyDefinitions &setting_definitions);
64 
65   // Subclass specific functions
66 
67   // Get the index of a property given its exact name in this property
68   // collection, "name" can't be a path to a property path that refers to a
69   // property within a property
70   virtual size_t GetPropertyIndex(llvm::StringRef name) const;
71 
72   // Get a property by exact name exists in this property collection, name can
73   // not be a path to a property path that refers to a property within a
74   // property
75   virtual const Property *
76   GetProperty(llvm::StringRef name,
77               const ExecutionContext *exe_ctx = nullptr) const;
78 
79   virtual const Property *
80   GetPropertyAtIndex(size_t idx,
81                      const ExecutionContext *exe_ctx = nullptr) const {
82     return ProtectedGetPropertyAtIndex(idx);
83   }
84 
85   // Property can be a property path like
86   // "target.process.extra-startup-command"
87   virtual const Property *
88   GetPropertyAtPath(const ExecutionContext *exe_ctx,
89                     llvm::StringRef property_path) const;
90 
91   virtual lldb::OptionValueSP
92   GetPropertyValueAtIndex(size_t idx, const ExecutionContext *exe_ctx) const;
93 
94   virtual lldb::OptionValueSP GetValueForKey(const ExecutionContext *exe_ctx,
95                                              llvm::StringRef key) const;
96 
97   lldb::OptionValueSP GetSubValue(const ExecutionContext *exe_ctx,
98                                   llvm::StringRef name,
99                                   Status &error) const override;
100 
101   Status SetSubValue(const ExecutionContext *exe_ctx, VarSetOperationType op,
102                      llvm::StringRef path, llvm::StringRef value) override;
103 
104   bool
105   GetPropertyAtIndexAsArgs(size_t idx, Args &args,
106                            const ExecutionContext *exe_ctx = nullptr) const;
107 
108   bool SetPropertyAtIndexFromArgs(size_t idx, const Args &args,
109                                   const ExecutionContext *exe_ctx = nullptr);
110 
111   OptionValueDictionary *GetPropertyAtIndexAsOptionValueDictionary(
112       size_t idx, const ExecutionContext *exe_ctx = nullptr) const;
113 
114   OptionValueSInt64 *GetPropertyAtIndexAsOptionValueSInt64(
115       size_t idx, const ExecutionContext *exe_ctx = nullptr) const;
116 
117   OptionValueUInt64 *GetPropertyAtIndexAsOptionValueUInt64(
118       size_t idx, const ExecutionContext *exe_ctx = nullptr) const;
119 
120   OptionValueString *GetPropertyAtIndexAsOptionValueString(
121       size_t idx, const ExecutionContext *exe_ctx = nullptr) const;
122 
123   OptionValueFileSpec *GetPropertyAtIndexAsOptionValueFileSpec(
124       size_t idx, const ExecutionContext *exe_ctx = nullptr) const;
125 
126   OptionValuePathMappings *GetPropertyAtIndexAsOptionValuePathMappings(
127       size_t idx, const ExecutionContext *exe_ctx = nullptr) const;
128 
129   OptionValueFileSpecList *GetPropertyAtIndexAsOptionValueFileSpecList(
130       size_t idx, const ExecutionContext *exe_ctx = nullptr) const;
131 
132   void AppendProperty(llvm::StringRef name, llvm::StringRef desc,
133                       bool is_global, const lldb::OptionValueSP &value_sp);
134 
135   lldb::OptionValuePropertiesSP GetSubProperty(const ExecutionContext *exe_ctx,
136                                                llvm::StringRef name);
137 
138   void SetValueChangedCallback(size_t property_idx,
139                                std::function<void()> callback);
140 
141   template <typename T>
142   auto GetPropertyAtIndexAs(size_t idx,
143                             const ExecutionContext *exe_ctx = nullptr) const {
144     if (const Property *property = GetPropertyAtIndex(idx, exe_ctx)) {
145       if (OptionValue *value = property->GetValue().get())
146         return value->GetValueAs<T>();
147     }
148     if constexpr (std::is_pointer_v<T>)
149       return T{nullptr};
150     else
151       return std::optional<T>{std::nullopt};
152   }
153 
154   template <typename T>
155   bool SetPropertyAtIndex(size_t idx, T t,
156                           const ExecutionContext *exe_ctx = nullptr) const {
157     if (const Property *property = GetPropertyAtIndex(idx, exe_ctx)) {
158       if (OptionValue *value = property->GetValue().get()) {
159         value->SetValueAs(t);
160         return true;
161       }
162     }
163     return false;
164   }
165 
166 protected:
167   Property *ProtectedGetPropertyAtIndex(size_t idx) {
168     assert(idx < m_properties.size() && "invalid property index");
169     return ((idx < m_properties.size()) ? &m_properties[idx] : nullptr);
170   }
171 
172   const Property *ProtectedGetPropertyAtIndex(size_t idx) const {
173     assert(idx < m_properties.size() && "invalid property index");
174     return ((idx < m_properties.size()) ? &m_properties[idx] : nullptr);
175   }
176 
177   std::string m_name;
178   std::vector<Property> m_properties;
179   llvm::StringMap<size_t> m_name_to_index;
180 };
181 
182 } // namespace lldb_private
183 
184 #endif // LLDB_INTERPRETER_OPTIONVALUEPROPERTIES_H
185