File: metadata_types.h

package info (click to toggle)
chromium 138.0.7204.183-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 6,071,908 kB
  • sloc: cpp: 34,937,088; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,953; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,806; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (235 lines) | stat: -rw-r--r-- 9,142 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef UI_BASE_METADATA_METADATA_TYPES_H_
#define UI_BASE_METADATA_METADATA_TYPES_H_

#include <map>
#include <memory>
#include <string>
#include <string_view>
#include <vector>

#include "base/callback_list.h"
#include "base/compiler_specific.h"
#include "base/component_export.h"
#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"

namespace ui {
namespace metadata {

enum class PropertyFlags : uint32_t {
  // By default, properties are read/write. This flag indicates that the given
  // property metadata instance needs no special attention.
  kEmpty = 0x00,
  // Property metadata instance should be treated as read-only. SetValueAsString
  // should not be called since there may not be a conversion from a string for
  // the type of the property. (see kIsSerializable below for additional info).
  // Calling SetValueAsString() may trigger a NOTREACHED() error under debug.
  kReadOnly = 0x01,
  // Property metadata can be serialized to or from a string. Needs to make sure
  // this flag is set to have meaningful SetValueAsString() and
  // GetValueFromString(). This is ultimately a signal indicating the underlying
  // TypeConverter is able to convert the value to/from a string.
  kSerializable = 0x100,
};

COMPONENT_EXPORT(UI_BASE_METADATA)
extern PropertyFlags operator|(PropertyFlags op1, PropertyFlags op2);
COMPONENT_EXPORT(UI_BASE_METADATA)
extern PropertyFlags operator&(PropertyFlags op1, PropertyFlags op2);
COMPONENT_EXPORT(UI_BASE_METADATA)
extern PropertyFlags operator^(PropertyFlags op1, PropertyFlags op2);
COMPONENT_EXPORT(UI_BASE_METADATA) extern bool operator!(PropertyFlags op);

// Used to identify the CallbackList<> within the PropertyChangedVectors map.
using PropertyKey = const void*;

// Used to generate property keys when a single field needs multiple property
// keys - for example, if you have a single "bounds" field which is a gfx::Rect
// and want to have four separate properties that all use that field, you can
// use MakeUniquePropertyKey() rather than using &bounds_ + 0, &bounds_ + 1,
// and so on. This avoids unsafe buffer use warnings.
static inline PropertyKey MakeUniquePropertyKey(PropertyKey base,
                                                uintptr_t offset) {
  return reinterpret_cast<PropertyKey>(reinterpret_cast<uintptr_t>(base) +
                                       offset);
}

using PropertyChangedCallbacks = base::RepeatingClosureList;
using PropertyChangedCallback = PropertyChangedCallbacks::CallbackType;

// Interface for classes that provide ClassMetaData (via macros in
// metadata_header_macros.h). GetClassMetaData() is automatically overridden and
// implemented in the relevant macros, so a class must merely have
// MetaDataProvider somewhere in its ancestry.
class COMPONENT_EXPORT(UI_BASE_METADATA) MetaDataProvider {
 public:
  MetaDataProvider();
  virtual ~MetaDataProvider();
  virtual const class ClassMetaData* GetClassMetaData() const = 0;
  class ClassMetaData* GetClassMetaData();

 protected:
  [[nodiscard]] base::CallbackListSubscription AddPropertyChangedCallback(
      PropertyKey property,
      PropertyChangedCallback callback);
  void TriggerChangedCallback(PropertyKey property);

 private:
  using PropertyChangedVectors =
      std::map<PropertyKey, std::unique_ptr<PropertyChangedCallbacks>>;

  // Property Changed Callbacks ------------------------------------------------
  PropertyChangedVectors property_changed_vectors_;
};

class MemberMetaDataBase;

// Represents the 'meta data' that describes a class. Using the appropriate
// macros in ui/base/metadata/metadata_impl_macros.h, a descendant of this
// class is declared within the scope of the containing class. See information
// about using the macros in the comment for the views::View class.
class COMPONENT_EXPORT(UI_BASE_METADATA) ClassMetaData {
 public:
  ClassMetaData();
  ClassMetaData(std::string_view file LIFETIME_BOUND, int line);
  ClassMetaData(const ClassMetaData&) = delete;
  ClassMetaData& operator=(const ClassMetaData&) = delete;
  virtual ~ClassMetaData();

  std::string_view type_name() const { return type_name_; }
  const std::vector<raw_ptr<MemberMetaDataBase, VectorExperimental>>& members()
      const {
    return members_;
  }
  const std::string_view file() const { return file_; }
  const int& line() const { return line_; }
  const std::string& GetUniqueName() const;
  void AddMemberData(std::unique_ptr<MemberMetaDataBase> member_data);

  // Lookup the member data entry for a member of this class with a given name.
  // Returns the appropriate MemberMetaDataBase* if it exists, nullptr
  // otherwise.
  MemberMetaDataBase* FindMemberData(const std::string& member_name);

  ClassMetaData* parent_class_meta_data() const {
    return parent_class_meta_data_;
  }
  void SetParentClassMetaData(ClassMetaData* parent_meta_data) {
    parent_class_meta_data_ = parent_meta_data;
  }

  // Custom iterator to iterate through all member data entries associated with
  // a class (including members declared in parent classes).
  // Example:
  //    for(views::MemberMetaDataBase* member : class_meta_data) {
  //      OperateOn(member);
  //    }
  class COMPONENT_EXPORT(UI_BASE_METADATA) ClassMemberIterator {
   public:
    using iterator_category = std::forward_iterator_tag;
    using value_type = MemberMetaDataBase*;
    using difference_type = std::ptrdiff_t;
    using pointer = MemberMetaDataBase**;
    using reference = MemberMetaDataBase*&;

    ClassMemberIterator(const ClassMemberIterator& other);
    ~ClassMemberIterator();

    ClassMemberIterator& operator++();
    ClassMemberIterator operator++(int);

    bool operator==(const ClassMemberIterator& rhs) const;

    MemberMetaDataBase* operator*() {
      if (current_collection_ == nullptr ||
          current_vector_index_ >= current_collection_->members().size())
        return nullptr;

      return current_collection_->members()[current_vector_index_];
    }

    // Returns true if iterator currently on last member for that current
    // collection.
    bool IsLastMember() const;

    std::string GetCurrentCollectionName() const;

   private:
    friend class ClassMetaData;
    explicit ClassMemberIterator(ClassMetaData* starting_container);
    void IncrementHelper();

    raw_ptr<ClassMetaData> current_collection_;
    size_t current_vector_index_;
  };

  ClassMemberIterator begin();
  ClassMemberIterator end();

 protected:
  void SetTypeName(std::string_view type_name);

 private:
  // `type_name_` is a static string stored in the binary.
  std::string_view type_name_;
  mutable std::string unique_name_;
  std::vector<raw_ptr<MemberMetaDataBase, VectorExperimental>> members_;
  raw_ptr<ClassMetaData> parent_class_meta_data_ = nullptr;
  const std::string_view file_;
  const int line_ = 0;
};

// Abstract base class to represent meta data about class members.
// Provides basic information (such as the name of the member), and templated
// accessors to get/set the value of the member on an object.
class COMPONENT_EXPORT(UI_BASE_METADATA) MemberMetaDataBase {
 public:
  using ValueStrings = std::vector<std::u16string>;

  MemberMetaDataBase(std::string member_name, std::string member_type)
      : member_name_(std::move(member_name)),
        member_type_(std::move(member_type)) {}
  MemberMetaDataBase(const MemberMetaDataBase&) = delete;
  MemberMetaDataBase& operator=(const MemberMetaDataBase&) = delete;
  virtual ~MemberMetaDataBase() = default;

  // Access the value of this member and return it as a string.
  // |obj| is the instance on which to obtain the value of the property this
  // metadata represents.
  virtual std::u16string GetValueAsString(void* obj) const = 0;

  // Set the value of this member through a string on a specified object.
  // |obj| is the instance on which to set the value of the property this
  // metadata represents.
  virtual void SetValueAsString(void* obj, const std::u16string& new_value);

  // Return various information flags about the property.
  virtual PropertyFlags GetPropertyFlags() const = 0;

  // Return a list of valid property values as a vector of strings. An empty
  // vector indicates that the natural limits of the underlying type applies.
  virtual ValueStrings GetValidValues() const;

  // Return an optional prefix string used by the ui-devtools frontend to
  // prepend to the member name which causes a special value editor to become
  // available. For instance, an SkColor member type would add the "--" string
  // which tells the frontend to display a color swatch and a color editing
  // dialog.
  virtual std::string_view GetMemberNamePrefix() const;

  const std::string& member_name() const { return member_name_; }
  const std::string& member_type() const { return member_type_; }

 private:
  std::string member_name_;
  std::string member_type_;
};  // class MemberMetaDataBase

}  // namespace metadata
}  // namespace ui

#endif  // UI_BASE_METADATA_METADATA_TYPES_H_