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