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