ConfigurationSetParser.h (8058B)
1 // Copyright (c) Microsoft Corporation. 2 // Licensed under the MIT License. 3 #pragma once 4 #include <ConfigurationUnit.h> 5 #include <ConfigurationSet.h> 6 #include <ConfigurationSetUtilities.h> 7 #include <winget/Yaml.h> 8 #include <winrt/Windows.Storage.Streams.h> 9 #include <functional> 10 #include <memory> 11 #include <string_view> 12 #include <utility> 13 #include <vector> 14 15 namespace winrt::Microsoft::Management::Configuration::implementation 16 { 17 // Interface for parsing a configuration set stream. 18 struct ConfigurationSetParser 19 { 20 // Create a parser from the given bytes (the encoding is detected). 21 static std::unique_ptr<ConfigurationSetParser> Create(std::string_view input); 22 23 // Create a parser for the given schema version. 24 static std::unique_ptr<ConfigurationSetParser> CreateForSchemaVersion(std::string schemaVersion); 25 26 // Determines if the given value is a recognized schema version. 27 // This will only return true for a version that we fully recognize. 28 static bool IsRecognizedSchemaVersion(hstring value); 29 30 // Determines if the given value is a recognized schema URI. 31 // This will only return true for a URI that we fully recognize. 32 static bool IsRecognizedSchemaUri(const Windows::Foundation::Uri& value); 33 34 // Gets the schema URI associated with the given version, or null if there is not one. 35 static Windows::Foundation::Uri GetSchemaUriForVersion(hstring value); 36 37 // Gets the schema version associated with the given URI, or null if there is not one. 38 static hstring GetSchemaVersionForUri(Windows::Foundation::Uri value); 39 40 // Gets the schema version associated with the given URI, or null if there is not one. 41 static std::string GetSchemaVersionForUri(std::string_view value); 42 43 // Gets the latest schema version. 44 static std::pair<hstring, Windows::Foundation::Uri> LatestVersion(); 45 46 virtual ~ConfigurationSetParser() noexcept = default; 47 48 ConfigurationSetParser(const ConfigurationSetParser&) = delete; 49 ConfigurationSetParser& operator=(const ConfigurationSetParser&) = delete; 50 ConfigurationSetParser(ConfigurationSetParser&&) = default; 51 ConfigurationSetParser& operator=(ConfigurationSetParser&&) = default; 52 53 // Parse the full document. 54 virtual void Parse() = 0; 55 56 // Retrieves the schema version of the parser. 57 virtual hstring GetSchemaVersion() = 0; 58 59 // Extracts (and removes) the environment information from the given metadata. 60 virtual void ExtractEnvironmentFromMetadata(Windows::Foundation::Collections::ValueSet valueSet, implementation::ConfigurationEnvironment& environment) = 0; 61 62 using ConfigurationSetPtr = winrt::com_ptr<implementation::ConfigurationSet>; 63 64 // Retrieve the configuration set from the parser. 65 ConfigurationSetPtr GetConfigurationSet() const { return m_configurationSet; } 66 67 // The latest result code from the parser. 68 hresult Result() const { return m_result; } 69 70 // The field related to the result code. 71 hstring Field() const { return m_field; } 72 73 // The value of the field. 74 hstring Value() const { return m_value; } 75 76 // The line related to the result code. 77 uint32_t Line() const { return m_line; } 78 79 // The column related to the result code. 80 uint32_t Column() const { return m_column; } 81 82 // Parse a ValueSet from the given input. 83 Windows::Foundation::Collections::ValueSet ParseValueSet(std::string_view input); 84 85 // Parse a string array from the given input. 86 std::vector<hstring> ParseStringArray(std::string_view input); 87 88 protected: 89 ConfigurationSetParser() = default; 90 91 // Sets (or resets) the document to parse. 92 virtual void SetDocument(AppInstaller::YAML::Node&& document) = 0; 93 94 // Set the error state 95 void SetError(hresult result, std::string_view field = {}, std::string_view value = {}, uint32_t line = 0, uint32_t column = 0); 96 void SetError(hresult result, std::string_view field, const AppInstaller::YAML::Mark& mark, std::string_view value = {}); 97 98 ConfigurationSetPtr m_configurationSet; 99 hresult m_result; 100 hstring m_field; 101 hstring m_value; 102 uint32_t m_line = 0; 103 uint32_t m_column = 0; 104 105 // Gets the given `field` from the `parent` node, checking against the requirement and type. 106 const AppInstaller::YAML::Node& GetAndEnsureField(const AppInstaller::YAML::Node& parent, ConfigurationField field, bool required, std::optional<AppInstaller::YAML::Node::Type> type); 107 108 // Errors if the given `field` is present. 109 void EnsureFieldAbsent(const AppInstaller::YAML::Node& parent, ConfigurationField field); 110 111 // Parse the ValueSet named `field` from the given `node`. 112 void ParseValueSet(const AppInstaller::YAML::Node& node, ConfigurationField field, bool required, const Windows::Foundation::Collections::ValueSet& valueSet); 113 114 // Parse the mapping named `field` from the given `node`. 115 void ParseMapping(const AppInstaller::YAML::Node& node, ConfigurationField field, bool required, AppInstaller::YAML::Node::Type elementType, std::function<void(std::string, const AppInstaller::YAML::Node&)> operation); 116 117 // Parse the sequence named `field` from the given `node`. 118 void ParseSequence(const AppInstaller::YAML::Node& node, ConfigurationField field, bool required, std::optional<AppInstaller::YAML::Node::Type> elementType, std::function<void(const AppInstaller::YAML::Node&)> operation); 119 120 // Parse the sequence from the given `node`. 121 void ParseSequence(const AppInstaller::YAML::Node& node, std::string_view nameForErrors, std::optional<AppInstaller::YAML::Node::Type> elementType, std::function<void(const AppInstaller::YAML::Node&)> operation); 122 123 // Gets the string value in `field` from the given `node`, setting this value on `unit` using the `propertyFunction`. 124 void GetStringValueForUnit(const AppInstaller::YAML::Node& node, ConfigurationField field, bool required, ConfigurationUnit* unit, void(ConfigurationUnit::* propertyFunction)(const hstring& value)); 125 126 // Gets the string array in `field` from the given `node`, setting this value on `unit` using the `propertyFunction`. 127 void GetStringArrayForUnit(const AppInstaller::YAML::Node& node, ConfigurationField field, bool required, ConfigurationUnit* unit, void(ConfigurationUnit::* propertyFunction)(std::vector<hstring>&& value)); 128 129 // Validates the unit's Type property for correctness and consistency with the metadata. Should be called after parsing the Metadata value. 130 void ValidateType(ConfigurationUnit* unit, const AppInstaller::YAML::Node& unitNode, ConfigurationField typeField, bool moveModuleNameToMetadata, bool moduleNameRequiredInType); 131 132 // Parses an object from the given node, attempting to treat it as the requested type if possible. 133 void ParseObject(const AppInstaller::YAML::Node& node, ConfigurationField fieldForErrors, Windows::Foundation::PropertyType type, Windows::Foundation::IInspectable& result); 134 135 // Extracts the security context from the metadata in the given unit; if not present use `defaultContext`. 136 void ExtractSecurityContext(implementation::ConfigurationUnit* unit, SecurityContext defaultContext = SecurityContext::Current); 137 void ExtractSecurityContext(Windows::Foundation::Collections::ValueSet metadata, implementation::ConfigurationEnvironment& environment, SecurityContext defaultContext = SecurityContext::Current); 138 139 private: 140 // Support older schema parsing. 141 static std::unique_ptr<ConfigurationSetParser> GetSchemaVersionFromOldFormat(AppInstaller::YAML::Node& document, std::string& schemaVersionString); 142 }; 143 }