Coverage Report

Created: 2026-02-09 06:05

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/CMake/Source/cmFileAPI.h
Line
Count
Source
1
/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
2
   file LICENSE.rst or https://cmake.org/licensing for details.  */
3
#pragma once
4
5
#include "cmConfigure.h" // IWYU pragma: keep
6
7
#include <map>
8
#include <memory>
9
#include <string>
10
#include <unordered_set>
11
#include <vector>
12
13
#include <cm3p/json/reader.h>
14
#include <cm3p/json/value.h>
15
#include <cm3p/json/writer.h>
16
17
class cmake;
18
19
class cmFileAPI
20
{
21
public:
22
  cmFileAPI(cmake* cm);
23
24
  /** Read fileapi queries from disk.  */
25
  void ReadQueries();
26
27
  /** Get the list of configureLog object kind versions requested.  */
28
  std::vector<unsigned int> GetConfigureLogVersions();
29
30
  /** Identify the situation in which WriteReplies is called.  */
31
  enum class IndexFor
32
  {
33
    Success,
34
    FailedConfigure,
35
    FailedCompute,
36
    FailedGenerate,
37
  };
38
39
  /** Write fileapi replies to disk.  */
40
  void WriteReplies(IndexFor indexFor);
41
42
  /** Get the "cmake" instance with which this was constructed.  */
43
0
  cmake* GetCMakeInstance() const { return this->CMakeInstance; }
44
45
  /** Convert a JSON object or array into an object with a single
46
      "jsonFile" member specifying a file named with the given prefix
47
      and holding the original object.  Other JSON types are unchanged.  */
48
  Json::Value MaybeJsonFile(Json::Value in, std::string const& prefix);
49
50
  /** Report file-api capabilities for cmake -E capabilities.  */
51
  static Json::Value ReportCapabilities();
52
53
  // Keep in sync with ObjectKindName.
54
  enum class ObjectKind
55
  {
56
    CodeModel,
57
    ConfigureLog,
58
    Cache,
59
    CMakeFiles,
60
    Toolchains,
61
    InternalTest
62
  };
63
64
  bool AddProjectQuery(ObjectKind kind, unsigned majorVersion,
65
                       unsigned minorVersion);
66
67
  /** Build a JSON object with major and minor fields.  */
68
  static Json::Value BuildVersion(unsigned int major, unsigned int minor);
69
70
private:
71
  cmake* CMakeInstance;
72
73
  /** The api/v1 directory location.  */
74
  std::string APIv1;
75
76
  /** api/v1 directory in the user's shared CMake config directory.  */
77
  std::string UserAPIv1;
78
79
  /** The set of files we have just written to the reply directory.  */
80
  std::unordered_set<std::string> ReplyFiles;
81
82
  static std::vector<std::string> LoadDir(std::string const& dir);
83
  void RemoveOldReplyFiles();
84
85
  /** Identify one object kind and major version.  */
86
  struct Object
87
  {
88
    ObjectKind Kind;
89
    unsigned int Version = 0;
90
    friend bool operator<(Object l, Object r)
91
0
    {
92
0
      if (l.Kind != r.Kind) {
93
0
        return l.Kind < r.Kind;
94
0
      }
95
0
      return l.Version < r.Version;
96
0
    }
97
    friend bool operator==(Object l, Object r)
98
0
    {
99
0
      return l.Kind == r.Kind && l.Version == r.Version;
100
0
    }
101
0
    friend bool operator!=(Object l, Object r) { return !(l == r); }
102
  };
103
104
  /** Represent content of a query directory.  */
105
  struct Query
106
  {
107
    /** Known object kind-version pairs.  */
108
    std::vector<Object> Known;
109
    /** Unknown object kind names.  */
110
    std::vector<std::string> Unknown;
111
  };
112
113
  /** Represent one request in a client 'query.json'.  */
114
  struct ClientRequest : public Object
115
  {
116
    /** Empty if request is valid, else the error string.  */
117
    std::string Error;
118
  };
119
120
  /** Represent the "requests" in a client 'query.json'.  */
121
  struct ClientRequests : public std::vector<ClientRequest>
122
  {
123
    /** Empty if requests field is valid, else the error string.  */
124
    std::string Error;
125
  };
126
127
  /** Represent the content of a client query.json file.  */
128
  struct ClientQueryJson
129
  {
130
    /** The error string if parsing failed, else empty.  */
131
    std::string Error;
132
133
    /** The 'query.json' object "client" member if it exists, else null.  */
134
    Json::Value ClientValue;
135
136
    /** The 'query.json' object "requests" member if it exists, else null.  */
137
    Json::Value RequestsValue;
138
139
    /** Requests extracted from 'query.json'.  */
140
    ClientRequests Requests;
141
  };
142
143
  /** Represent content of a client query directory.  */
144
  struct ClientQuery
145
  {
146
    /** The content of the client query directory except 'query.json'.  */
147
    Query DirQuery;
148
149
    /** True if 'query.json' exists.  */
150
    bool HaveQueryJson = false;
151
152
    /** The 'query.json' content.  */
153
    ClientQueryJson QueryJson;
154
  };
155
156
  /** Whether the top-level query directory exists at all.  */
157
  bool QueryExists = false;
158
159
  /** The content of the top-level query directory.  */
160
  Query TopQuery;
161
162
  /** The content of each "client-$client" query directory.  */
163
  std::map<std::string, ClientQuery> ClientQueries;
164
165
  /** Reply index object generated for object kind/version.
166
      This populates the "objects" field of the reply index.  */
167
  std::map<Object, Json::Value> ReplyIndexObjects;
168
169
  /** Identify the situation in which WriteReplies was called.  */
170
  IndexFor ReplyIndexFor = IndexFor::Success;
171
172
  std::unique_ptr<Json::CharReader> JsonReader;
173
  std::unique_ptr<Json::StreamWriter> JsonWriter;
174
175
  bool ReadJsonFile(std::string const& file, Json::Value& value,
176
                    std::string& error);
177
178
  std::string WriteJsonFile(
179
    Json::Value const& value, std::string const& prefix,
180
    std::string (*computeSuffix)(std::string const&) = ComputeSuffixHash);
181
  static std::string ComputeSuffixHash(std::string const&);
182
  static std::string ComputeSuffixTime(std::string const&);
183
184
  static bool ReadQuery(std::string const& query,
185
                        std::vector<Object>& objects);
186
  void ReadClient(std::string const& client);
187
  void ReadClientQuery(std::string const& client, ClientQueryJson& q);
188
189
  Json::Value BuildReplyIndex();
190
  Json::Value BuildCMake();
191
  Json::Value BuildReply(Query const& q);
192
  Json::Value BuildReplyEntry(Object object);
193
  static Json::Value BuildReplyError(std::string const& error);
194
  Json::Value const& AddReplyIndexObject(Object o);
195
196
  static char const* ObjectKindName(ObjectKind kind);
197
  static std::string ObjectName(Object o);
198
199
  Json::Value BuildObject(Object object);
200
201
  ClientRequests BuildClientRequests(Json::Value const& requests);
202
  ClientRequest BuildClientRequest(Json::Value const& request);
203
  Json::Value BuildClientReply(ClientQuery const& q);
204
  Json::Value BuildClientReplyResponses(ClientRequests const& requests);
205
  Json::Value BuildClientReplyResponse(ClientRequest const& request);
206
207
  struct RequestVersion
208
  {
209
    unsigned int Major = 0;
210
    unsigned int Minor = 0;
211
  };
212
  static bool ReadRequestVersions(Json::Value const& version,
213
                                  std::vector<RequestVersion>& versions,
214
                                  std::string& error);
215
  static bool ReadRequestVersion(Json::Value const& version, bool inArray,
216
                                 std::vector<RequestVersion>& result,
217
                                 std::string& error);
218
  static std::string NoSupportedVersion(
219
    std::vector<RequestVersion> const& versions);
220
221
  void BuildClientRequestCodeModel(
222
    ClientRequest& r, std::vector<RequestVersion> const& versions);
223
  Json::Value BuildCodeModel(Object object);
224
225
  void BuildClientRequestConfigureLog(
226
    ClientRequest& r, std::vector<RequestVersion> const& versions);
227
  Json::Value BuildConfigureLog(Object object);
228
229
  void BuildClientRequestCache(ClientRequest& r,
230
                               std::vector<RequestVersion> const& versions);
231
  Json::Value BuildCache(Object object);
232
233
  void BuildClientRequestCMakeFiles(
234
    ClientRequest& r, std::vector<RequestVersion> const& versions);
235
  Json::Value BuildCMakeFiles(Object object);
236
237
  void BuildClientRequestToolchains(
238
    ClientRequest& r, std::vector<RequestVersion> const& versions);
239
  Json::Value BuildToolchains(Object object);
240
241
  void BuildClientRequestInternalTest(
242
    ClientRequest& r, std::vector<RequestVersion> const& versions);
243
  Json::Value BuildInternalTest(Object object);
244
};