My Project
KeywordValidation.hpp
1 /*
2  Copyright 2021 Equinor.
3 
4  This file is part of the Open Porous Media project (OPM).
5 
6  OPM is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  OPM is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with OPM. If not, see <http://www.gnu.org/licenses/>.
18 */
19 
20 #ifndef OPM_KEYWORDVALIDATION_HEADER_INCLUDED
21 #define OPM_KEYWORDVALIDATION_HEADER_INCLUDED
22 
23 #include <opm/common/OpmLog/KeywordLocation.hpp>
24 
25 #include <functional>
26 #include <initializer_list>
27 #include <map>
28 #include <optional>
29 #include <string>
30 #include <unordered_map>
31 #include <vector>
32 
33 namespace Opm
34 {
35 
36 class Deck;
37 class DeckKeyword;
38 class ErrorGuard;
39 class ParseContext;
40 
41 namespace KeywordValidation
42 {
43  // Describe an unsupported keyword:
45  bool critical; // Set to true if presence of the keyword should be an error
46  std::optional<std::string> message; // An optional message to show if the keyword is present
47  };
48 
49  // Describe a partially supported keyword item, by listing legal values:
50  template <typename T>
52  bool critical; // Set to true if the unsupported item value should be an error
53  std::function<bool(T)> validator; // Predicate function to test values
54  std::optional<std::string> message; // An optional message to show if an illegal item is encountered
55  };
56 
57  // This is used to list unsupported kewyords.
58  using UnsupportedKeywords = std::map<std::string, UnsupportedKeywordProperties>;
59 
60  // This is used to list the partially supported items of a keyword:
61  template <typename T>
62  using PartiallySupportedKeywordItems = std::map<size_t, PartiallySupportedKeywordProperties<T>>;
63 
64  // This is used to list the keywords that have partially supported items:
65  template <typename T>
66  using PartiallySupportedKeywords = std::map<std::string, PartiallySupportedKeywordItems<T>>;
67 
68  // This contains the information needed to report a single error occurence.
69  // The validator will construct a vector of these, copying the relevant
70  // information from the properties of the offending keywords and items.
71  struct ValidationError {
72  bool critical; // Determines if the encountered problem should be an error or a warning
73  KeywordLocation location; // Location information (keyword name, file and line number)
74  size_t record_number; // Number of the offending record
75  std::optional<size_t> item_number; // Number of the offending item
76  std::optional<std::string> item_value; // The offending value of a problematic item
77  std::optional<std::string> user_message; // An optional message to show if a problem is encountered
78  };
79 
80  // Get a formatted error report from a vector of validation errors. Set
81  // critical to true if the report should contain only critical errors. If
82  // critical is false, only non-critical errors are reported. If not
83  // critical/non-critical errors are present, but the critical flag to reset
84  // them, the result will be an empty string.
85  std::string get_error_report(const std::vector<ValidationError>& errors, const bool critical);
86 
87 
88 
89  // These are special case validation functions for keyword which do not fit nicely into the general
90  // validation framework. The validation function itself is void, but error conditions are signalled by
91  // appending ValidationError instances to the @errors vector.
92  void validateBRINE(const DeckKeyword& keyword, std::vector<ValidationError>& errors);
93 
95  {
96  public:
97  KeywordValidator(const UnsupportedKeywords& keywords,
98  const PartiallySupportedKeywords<std::string>& string_items,
99  const PartiallySupportedKeywords<int>& int_items,
100  const PartiallySupportedKeywords<double>& double_items,
101  const std::unordered_map<std::string, std::function<void(const DeckKeyword& keyword, std::vector<ValidationError>& errors)>>& special_validation)
102  : m_keywords(keywords)
103  , m_string_items(string_items)
104  , m_int_items(int_items)
105  , m_double_items(double_items)
106  , m_special_validation(special_validation)
107  {
108  }
109 
110  // Validate a deck, reporting warnings and errors. If there are only
111  // warnings, these will be reported. If there are errors, these are
112  // reported, and execution of the program is halted.
113  void validateDeck(const Deck& deck,
114  const ParseContext& parse_context,
115  ErrorGuard& error_guard) const;
116 
117  // Validate a single deck keyword. If a problem is encountered, add the
118  // relevant information to the errors vector.
119  void validateDeckKeyword(const DeckKeyword& keyword, std::vector<ValidationError>& errors) const;
120 
121  private:
122  template <typename T>
123  void validateKeywordItem(const DeckKeyword& keyword,
124  const PartiallySupportedKeywordProperties<T>& properties,
125  const bool multiple_records,
126  const size_t record_number,
127  const size_t item_number,
128  const T& item_value,
129  std::vector<ValidationError>& errors) const;
130 
131 
132  template <typename T>
133  void validateKeywordItems(const DeckKeyword& keyword,
134  const PartiallySupportedKeywords<T>& partially_supported_options,
135  std::vector<ValidationError>& errors) const;
136 
137  const UnsupportedKeywords m_keywords;
138  const PartiallySupportedKeywords<std::string> m_string_items;
139  const PartiallySupportedKeywords<int> m_int_items;
140  const PartiallySupportedKeywords<double> m_double_items;
141  const std::unordered_map<std::string, std::function<void(const DeckKeyword& keyword, std::vector<ValidationError>& errors)>> m_special_validation;
142  };
143 
144 
145  // Helper class to test if a given value is with a list of allowed values.
146  template <typename T>
148  {
149  public:
150  allow_values(const std::initializer_list<T>& allowed_values)
151  {
152  for (auto item : allowed_values) {
153  m_allowed_values.push_back(item);
154  }
155  }
156 
157  bool operator()(const T& value) const
158  {
159  return std::find(m_allowed_values.begin(), m_allowed_values.end(), value) != m_allowed_values.end();
160  }
161 
162  private:
163  std::vector<T> m_allowed_values;
164  };
165 
166 
167 } // namespace KeywordValidation
168 
169 } // namespace Opm
170 
171 
172 #endif
Definition: KeywordValidation.hpp:95
Definition: KeywordValidation.hpp:148
This file contains a set of helper functions used by VFPProd / VFPInj.
Definition: BlackoilPhases.hpp:26
Definition: KeywordValidation.hpp:44
Definition: KeywordValidation.hpp:71