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