Coverage Report

Created: 2026-07-30 06:52

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