• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // © 2024 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
3 
4 #include "unicode/utypes.h"
5 
6 #if !UCONFIG_NO_FORMATTING
7 
8 #if !UCONFIG_NO_MF2
9 
10 #include "messageformat2_allocation.h"
11 #include "messageformat2_errors.h"
12 #include "messageformat2_macros.h"
13 #include "uvector.h" // U_ASSERT
14 
15 U_NAMESPACE_BEGIN
16 
17 namespace message2 {
18 
19     // Errors
20     // -----------
21 
setFormattingError(const FunctionName & formatterName,UErrorCode & status)22     void DynamicErrors::setFormattingError(const FunctionName& formatterName, UErrorCode& status) {
23         addError(DynamicError(DynamicErrorType::FormattingError, formatterName), status);
24     }
25 
setFormattingError(UErrorCode & status)26     void DynamicErrors::setFormattingError(UErrorCode& status) {
27         addError(DynamicError(DynamicErrorType::FormattingError, UnicodeString("unknown formatter")), status);
28     }
29 
setOperandMismatchError(const FunctionName & formatterName,UErrorCode & status)30     void DynamicErrors::setOperandMismatchError(const FunctionName& formatterName, UErrorCode& status) {
31         addError(DynamicError(DynamicErrorType::OperandMismatchError, formatterName), status);
32     }
33 
setDuplicateOptionName(UErrorCode & status)34     void StaticErrors::setDuplicateOptionName(UErrorCode& status) {
35         addError(StaticError(StaticErrorType::DuplicateOptionName), status);
36     }
37 
setMissingSelectorAnnotation(UErrorCode & status)38     void StaticErrors::setMissingSelectorAnnotation(UErrorCode& status) {
39         addError(StaticError(StaticErrorType::MissingSelectorAnnotation), status);
40     }
41 
setSelectorError(const FunctionName & selectorName,UErrorCode & status)42     void DynamicErrors::setSelectorError(const FunctionName& selectorName, UErrorCode& status) {
43         addError(DynamicError(DynamicErrorType::SelectorError, selectorName), status);
44     }
45 
setUnknownFunction(const FunctionName & functionName,UErrorCode & status)46     void DynamicErrors::setUnknownFunction(const FunctionName& functionName, UErrorCode& status) {
47         addError(DynamicError(DynamicErrorType::UnknownFunction, functionName), status);
48     }
49 
setUnresolvedVariable(const VariableName & v,UErrorCode & status)50     void DynamicErrors::setUnresolvedVariable(const VariableName& v, UErrorCode& status) {
51         addError(DynamicError(DynamicErrorType::UnresolvedVariable, v), status);
52     }
53 
DynamicErrors(const StaticErrors & e,UErrorCode & status)54     DynamicErrors::DynamicErrors(const StaticErrors& e, UErrorCode& status) : staticErrors(e) {
55         resolutionAndFormattingErrors.adoptInstead(createUVector(status));
56     }
57 
StaticErrors(UErrorCode & status)58     StaticErrors::StaticErrors(UErrorCode& status) {
59         syntaxAndDataModelErrors.adoptInstead(createUVector(status));
60     }
61 
StaticErrors(StaticErrors && other)62     StaticErrors::StaticErrors(StaticErrors&& other) noexcept {
63         U_ASSERT(other.syntaxAndDataModelErrors.isValid());
64         syntaxAndDataModelErrors.adoptInstead(other.syntaxAndDataModelErrors.orphan());
65         dataModelError = other.dataModelError;
66         missingSelectorAnnotationError = other.missingSelectorAnnotationError;
67         syntaxError = other.syntaxError;
68     }
69 
StaticErrors(const StaticErrors & other,UErrorCode & errorCode)70     StaticErrors::StaticErrors(const StaticErrors& other, UErrorCode& errorCode) {
71         CHECK_ERROR(errorCode);
72 
73         U_ASSERT(other.syntaxAndDataModelErrors.isValid());
74         syntaxAndDataModelErrors.adoptInstead(createUVector(errorCode));
75         CHECK_ERROR(errorCode);
76         for (int32_t i = 0; i < other.syntaxAndDataModelErrors->size(); i++) {
77             StaticError* e = static_cast<StaticError*>(other.syntaxAndDataModelErrors->elementAt(i));
78             U_ASSERT(e != nullptr);
79             StaticError* copy = new StaticError(*e);
80             if (copy == nullptr) {
81                 errorCode = U_MEMORY_ALLOCATION_ERROR;
82                 return;
83             }
84             syntaxAndDataModelErrors->adoptElement(copy, errorCode);
85         }
86         dataModelError = other.dataModelError;
87         missingSelectorAnnotationError = other.missingSelectorAnnotationError;
88         syntaxError = other.syntaxError;
89     }
90 
count() const91     int32_t DynamicErrors::count() const {
92         U_ASSERT(resolutionAndFormattingErrors.isValid() && staticErrors.syntaxAndDataModelErrors.isValid());
93         return resolutionAndFormattingErrors->size() + staticErrors.syntaxAndDataModelErrors->size();
94     }
95 
hasError() const96     bool DynamicErrors::hasError() const {
97         return count() > 0;
98     }
99 
hasStaticError() const100     bool DynamicErrors::hasStaticError() const {
101         U_ASSERT(staticErrors.syntaxAndDataModelErrors.isValid());
102         return staticErrors.syntaxAndDataModelErrors->size() > 0;
103     }
104 
first() const105     const DynamicError& DynamicErrors::first() const {
106         U_ASSERT(resolutionAndFormattingErrors->size() > 0);
107         return *static_cast<DynamicError*>(resolutionAndFormattingErrors->elementAt(0));
108     }
109 
checkErrors(UErrorCode & status) const110     void DynamicErrors::checkErrors(UErrorCode& status) const {
111         if (status != U_ZERO_ERROR) {
112             return;
113         }
114 
115         // Just handle the first error
116         // TODO: Eventually want to return all errors to caller
117         if (count() == 0) {
118             return;
119         }
120         staticErrors.checkErrors(status);
121         if (U_FAILURE(status)) {
122             return;
123         }
124             U_ASSERT(resolutionAndFormattingErrors->size() > 0);
125             switch (first().type) {
126             case DynamicErrorType::UnknownFunction: {
127                 status = U_MF_UNKNOWN_FUNCTION_ERROR;
128                 break;
129             }
130             case DynamicErrorType::UnresolvedVariable: {
131                 status = U_MF_UNRESOLVED_VARIABLE_ERROR;
132                 break;
133             }
134             case DynamicErrorType::FormattingError: {
135                 status = U_MF_FORMATTING_ERROR;
136                 break;
137             }
138             case DynamicErrorType::OperandMismatchError: {
139                 status = U_MF_OPERAND_MISMATCH_ERROR;
140                 break;
141             }
142             case DynamicErrorType::SelectorError: {
143                 status = U_MF_SELECTOR_ERROR;
144                 break;
145             }
146             }
147     }
148 
addSyntaxError(UErrorCode & status)149     void StaticErrors::addSyntaxError(UErrorCode& status) {
150         addError(StaticError(StaticErrorType::SyntaxError), status);
151     }
152 
addError(StaticError && e,UErrorCode & status)153     void StaticErrors::addError(StaticError&& e, UErrorCode& status) {
154         CHECK_ERROR(status);
155 
156         StaticErrorType type = e.type;
157 
158         void* errorP = static_cast<void*>(create<StaticError>(std::move(e), status));
159         U_ASSERT(syntaxAndDataModelErrors.isValid());
160 
161         switch (type) {
162         case StaticErrorType::SyntaxError: {
163             syntaxError = true;
164             break;
165         }
166         case StaticErrorType::DuplicateDeclarationError: {
167             dataModelError = true;
168             break;
169         }
170         case StaticErrorType::DuplicateOptionName: {
171             dataModelError = true;
172             break;
173         }
174         case StaticErrorType::VariantKeyMismatchError: {
175             dataModelError = true;
176             break;
177         }
178         case StaticErrorType::DuplicateVariant: {
179             dataModelError = true;
180             break;
181         }
182         case StaticErrorType::NonexhaustivePattern: {
183             dataModelError = true;
184             break;
185         }
186         case StaticErrorType::MissingSelectorAnnotation: {
187             missingSelectorAnnotationError = true;
188             dataModelError = true;
189             break;
190         }
191         }
192         syntaxAndDataModelErrors->adoptElement(errorP, status);
193     }
194 
addError(DynamicError && e,UErrorCode & status)195     void DynamicErrors::addError(DynamicError&& e, UErrorCode& status) {
196         CHECK_ERROR(status);
197 
198         DynamicErrorType type = e.type;
199 
200         void* errorP = static_cast<void*>(create<DynamicError>(std::move(e), status));
201         U_ASSERT(resolutionAndFormattingErrors.isValid());
202 
203         switch (type) {
204         case DynamicErrorType::UnresolvedVariable: {
205             unresolvedVariableError = true;
206             resolutionAndFormattingErrors->adoptElement(errorP, status);
207             break;
208         }
209         case DynamicErrorType::FormattingError: {
210             formattingError = true;
211             resolutionAndFormattingErrors->adoptElement(errorP, status);
212             break;
213         }
214         case DynamicErrorType::OperandMismatchError: {
215             formattingError = true;
216             resolutionAndFormattingErrors->adoptElement(errorP, status);
217             break;
218         }
219         case DynamicErrorType::SelectorError: {
220             selectorError = true;
221             resolutionAndFormattingErrors->adoptElement(errorP, status);
222             break;
223         }
224         case DynamicErrorType::UnknownFunction: {
225             unknownFunctionError = true;
226             resolutionAndFormattingErrors->adoptElement(errorP, status);
227             break;
228         }
229         }
230     }
231 
checkErrors(UErrorCode & status) const232     void StaticErrors::checkErrors(UErrorCode& status) const {
233         if (U_FAILURE(status)) {
234             return;
235         }
236         if (syntaxAndDataModelErrors->size() > 0) {
237             switch (first().type) {
238             case StaticErrorType::DuplicateDeclarationError: {
239                 status = U_MF_DUPLICATE_DECLARATION_ERROR;
240                 break;
241             }
242             case StaticErrorType::DuplicateOptionName: {
243                 status = U_MF_DUPLICATE_OPTION_NAME_ERROR;
244                 break;
245             }
246             case StaticErrorType::VariantKeyMismatchError: {
247                 status = U_MF_VARIANT_KEY_MISMATCH_ERROR;
248                 break;
249             }
250             case StaticErrorType::DuplicateVariant: {
251                 status = U_MF_DUPLICATE_VARIANT_ERROR;
252                 break;
253             }
254             case StaticErrorType::NonexhaustivePattern: {
255                 status = U_MF_NONEXHAUSTIVE_PATTERN_ERROR;
256                 break;
257             }
258             case StaticErrorType::MissingSelectorAnnotation: {
259                 status = U_MF_MISSING_SELECTOR_ANNOTATION_ERROR;
260                 break;
261             }
262             case StaticErrorType::SyntaxError: {
263                 status = U_MF_SYNTAX_ERROR;
264                 break;
265             }
266             }
267         }
268     }
269 
first() const270     const StaticError& StaticErrors::first() const {
271         U_ASSERT(syntaxAndDataModelErrors.isValid() && syntaxAndDataModelErrors->size() > 0);
272         return *static_cast<StaticError*>(syntaxAndDataModelErrors->elementAt(0));
273     }
274 
~StaticErrors()275     StaticErrors::~StaticErrors() {}
~DynamicErrors()276     DynamicErrors::~DynamicErrors() {}
277 
278     template<typename ErrorType>
~Error()279     Error<ErrorType>::~Error() {}
280 
281     template<>
~Error()282     Error<StaticErrorType>::~Error() {}
283     template<>
~Error()284     Error<DynamicErrorType>::~Error() {}
285 
286 } // namespace message2
287 
288 U_NAMESPACE_END
289 
290 #endif /* #if !UCONFIG_NO_MF2 */
291 
292 #endif /* #if !UCONFIG_NO_FORMATTING */
293