cmFileAPI.h 7.7 KB

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