|
|
|||
File indexing completed on 2026-01-07 10:23:59
0001 // © 2024 and later: Unicode, Inc. and others. 0002 // License & terms of use: http://www.unicode.org/copyright.html 0003 0004 #include "unicode/utypes.h" 0005 0006 #ifndef MESSAGEFORMAT2_H 0007 #define MESSAGEFORMAT2_H 0008 0009 #if U_SHOW_CPLUSPLUS_API 0010 0011 #if !UCONFIG_NO_FORMATTING 0012 0013 #if !UCONFIG_NO_MF2 0014 0015 /** 0016 * \file 0017 * \brief C++ API: Formats messages using the draft MessageFormat 2.0. 0018 */ 0019 0020 #include "unicode/messageformat2_arguments.h" 0021 #include "unicode/messageformat2_data_model.h" 0022 #include "unicode/messageformat2_function_registry.h" 0023 #include "unicode/unistr.h" 0024 0025 #ifndef U_HIDE_DEPRECATED_API 0026 0027 U_NAMESPACE_BEGIN 0028 0029 namespace message2 { 0030 0031 class Environment; 0032 class MessageContext; 0033 class ResolvedSelector; 0034 class StaticErrors; 0035 0036 /** 0037 * <p>MessageFormatter is a Technical Preview API implementing MessageFormat 2.0. 0038 * 0039 * <p>See <a target="github" href="https://github.com/unicode-org/message-format-wg/blob/main/spec/syntax.md">the 0040 * description of the syntax with examples and use cases</a> and the corresponding 0041 * <a target="github" href="https://github.com/unicode-org/message-format-wg/blob/main/spec/message.abnf">ABNF</a> grammar.</p> 0042 * 0043 * The MessageFormatter class is mutable and movable. It is not copyable. 0044 * (It is mutable because if it has a custom function registry, the registry may include 0045 * `FormatterFactory` objects implementing custom formatters, which are allowed to contain 0046 * mutable state.) 0047 * 0048 * @internal ICU 75 technology preview 0049 * @deprecated This API is for technology preview only. 0050 */ 0051 class U_I18N_API MessageFormatter : public UObject { 0052 // Note: This class does not currently inherit from the existing 0053 // `Format` class. 0054 public: 0055 /** 0056 * Move assignment operator: 0057 * The source MessageFormatter will be left in a valid but undefined state. 0058 * 0059 * @internal ICU 75 technology preview 0060 * @deprecated This API is for technology preview only. 0061 */ 0062 MessageFormatter& operator=(MessageFormatter&&) noexcept; 0063 /** 0064 * Destructor. 0065 * 0066 * @internal ICU 75 technology preview 0067 * @deprecated This API is for technology preview only. 0068 */ 0069 virtual ~MessageFormatter(); 0070 0071 /** 0072 * Formats the message to a string, using the data model that was previously set or parsed, 0073 * and the given `arguments` object. 0074 * 0075 * @param arguments Reference to message arguments 0076 * @param status Input/output error code used to indicate syntax errors, data model 0077 * errors, resolution errors, formatting errors, selection errors, as well 0078 * as other errors (such as memory allocation failures). Partial output 0079 * is still provided in the presence of most error types. 0080 * @return The string result of formatting the message with the given arguments. 0081 * 0082 * @internal ICU 75 technology preview 0083 * @deprecated This API is for technology preview only. 0084 */ 0085 UnicodeString formatToString(const MessageArguments& arguments, UErrorCode &status); 0086 0087 /** 0088 * Not yet implemented; formats the message to a `FormattedMessage` object, 0089 * using the data model that was previously set or parsed, 0090 * and the given `arguments` object. 0091 * 0092 * @param arguments Reference to message arguments 0093 * @param status Input/output error code used to indicate syntax errors, data model 0094 * errors, resolution errors, formatting errors, selection errors, as well 0095 * as other errors (such as memory allocation failures). Partial output 0096 * is still provided in the presence of most error types. 0097 * @return The `FormattedMessage` representing the formatted message. 0098 * 0099 * @internal ICU 75 technology preview 0100 * @deprecated This API is for technology preview only. 0101 */ 0102 FormattedMessage format(const MessageArguments& arguments, UErrorCode &status) const { 0103 (void) arguments; 0104 if (U_SUCCESS(status)) { 0105 status = U_UNSUPPORTED_ERROR; 0106 } 0107 return FormattedMessage(status); 0108 } 0109 0110 /** 0111 * Accesses the locale that this `MessageFormatter` object was created with. 0112 * 0113 * @return A reference to the locale. 0114 * 0115 * @internal ICU 75 technology preview 0116 * @deprecated This API is for technology preview only. 0117 */ 0118 const Locale& getLocale() const { return locale; } 0119 0120 /** 0121 * Serializes the data model as a string in MessageFormat 2.0 syntax. 0122 * 0123 * @return result A string representation of the data model. 0124 * The string is a valid MessageFormat 2.0 message. 0125 * 0126 * @internal ICU 75 technology preview 0127 * @deprecated This API is for technology preview only. 0128 */ 0129 UnicodeString getPattern() const; 0130 0131 /** 0132 * Accesses the data model referred to by this 0133 * `MessageFormatter` object. 0134 * 0135 * @return A reference to the data model. 0136 * 0137 * @internal ICU 75 technology preview 0138 * @deprecated This API is for technology preview only. 0139 */ 0140 const MFDataModel& getDataModel() const; 0141 0142 /** 0143 * Used in conjunction with the 0144 * MessageFormatter::Builder::setErrorHandlingBehavior() method. 0145 * 0146 * @internal ICU 76 technology preview 0147 * @deprecated This API is for technology preview only. 0148 */ 0149 typedef enum UMFErrorHandlingBehavior { 0150 /** 0151 * Suppress errors and return best-effort output. 0152 * 0153 * @internal ICU 76 technology preview 0154 * @deprecated This API is for technology preview only. 0155 */ 0156 U_MF_BEST_EFFORT = 0, 0157 /** 0158 * Signal all MessageFormat errors using the UErrorCode 0159 * argument. 0160 * 0161 * @internal ICU 76 technology preview 0162 * @deprecated This API is for technology preview only. 0163 */ 0164 U_MF_STRICT 0165 } UMFErrorHandlingBehavior; 0166 0167 /** 0168 * The mutable Builder class allows each part of the MessageFormatter to be initialized 0169 * separately; calling its `build()` method yields an immutable MessageFormatter. 0170 * 0171 * Not copyable or movable. 0172 */ 0173 class U_I18N_API Builder : public UObject { 0174 private: 0175 friend class MessageFormatter; 0176 0177 // The pattern to be parsed to generate the formatted message 0178 UnicodeString pattern; 0179 bool hasPattern = false; 0180 bool hasDataModel = false; 0181 // The data model to be used to generate the formatted message 0182 // Initialized either by `setDataModel()`, or by the parser 0183 // through a call to `setPattern()` 0184 MFDataModel dataModel; 0185 // Normalized representation of the pattern; 0186 // ignored if `setPattern()` wasn't called 0187 UnicodeString normalizedInput; 0188 // Errors (internal representation of parse errors) 0189 // Ignored if `setPattern()` wasn't called 0190 StaticErrors* errors; 0191 Locale locale; 0192 // Not owned 0193 const MFFunctionRegistry* customMFFunctionRegistry; 0194 // Error behavior; see comment in `MessageFormatter` class 0195 bool signalErrors = false; 0196 0197 void clearState(); 0198 public: 0199 /** 0200 * Sets the locale to use for formatting. 0201 * 0202 * @param locale The desired locale. 0203 * @return A reference to the builder. 0204 * 0205 * @internal ICU 75 technology preview 0206 * @deprecated This API is for technology preview only. 0207 */ 0208 Builder& setLocale(const Locale& locale); 0209 /** 0210 * Sets the pattern (contents of the message) and parses it 0211 * into a data model. If a data model was 0212 * previously set, it is removed. 0213 * 0214 * @param pattern A string in MessageFormat 2.0 syntax. 0215 * @param parseError Struct to receive information on the position 0216 * of an error within the pattern. 0217 * @param status Input/output error code. If the 0218 * pattern cannot be parsed, set to failure code. 0219 * @return A reference to the builder. 0220 * 0221 * @internal ICU 75 technology preview 0222 * @deprecated This API is for technology preview only. 0223 */ 0224 Builder& setPattern(const UnicodeString& pattern, UParseError& parseError, UErrorCode& status); 0225 /** 0226 * Sets a custom function registry. 0227 * 0228 * @param functionRegistry Reference to the function registry to use. 0229 * `functionRegistry` is not copied, 0230 * and the caller must ensure its lifetime contains 0231 * the lifetime of the `MessageFormatter` object built by this 0232 * builder. 0233 * @return A reference to the builder. 0234 * 0235 * @internal ICU 75 technology preview 0236 * @deprecated This API is for technology preview only. 0237 */ 0238 Builder& setFunctionRegistry(const MFFunctionRegistry& functionRegistry); 0239 /** 0240 * Sets a data model. If a pattern was previously set, it is removed. 0241 * 0242 * @param dataModel Data model to format. Passed by move. 0243 * @return A reference to the builder. 0244 * 0245 * @internal ICU 75 technology preview 0246 * @deprecated This API is for technology preview only. 0247 */ 0248 Builder& setDataModel(MFDataModel&& dataModel); 0249 /** 0250 * Set the error handling behavior for this formatter. 0251 * 0252 * "Strict" error behavior means that that formatting methods 0253 * will set their UErrorCode arguments to signal MessageFormat 0254 * data model, resolution, and runtime errors. Syntax errors are 0255 * always signaled. 0256 * 0257 * "Best effort" error behavior means that MessageFormat errors are 0258 * suppressed: formatting methods will _not_ set their 0259 * UErrorCode arguments to signal MessageFormat data model, 0260 * resolution, or runtime errors. Best-effort output 0261 * will be returned. Syntax errors are always signaled. 0262 * This is the default behavior. 0263 * 0264 * @param type An enum with type UMFErrorHandlingBehavior; 0265 * if type == `U_MF_STRICT`, then 0266 * errors are handled strictly. 0267 * If type == `U_MF_BEST_EFFORT`, then 0268 * best-effort output is returned. 0269 * 0270 * The default is to suppress all MessageFormat errors 0271 * and return best-effort output. 0272 * 0273 * @return A reference to the builder. 0274 * 0275 * @internal ICU 76 technology preview 0276 * @deprecated This API is for technology preview only. 0277 */ 0278 Builder& setErrorHandlingBehavior(UMFErrorHandlingBehavior type); 0279 /** 0280 * Constructs a new immutable MessageFormatter using the pattern or data model 0281 * that was previously set, and the locale (if it was previously set) 0282 * or default locale (otherwise). 0283 * 0284 * The builder object (`this`) can still be used after calling `build()`. 0285 * 0286 * @param status Input/output error code. If neither the pattern 0287 * nor the data model is set, set to failure code. 0288 * @return The new MessageFormatter object 0289 * 0290 * @internal ICU 75 technology preview 0291 * @deprecated This API is for technology preview only. 0292 */ 0293 MessageFormatter build(UErrorCode& status) const; 0294 /** 0295 * Default constructor. 0296 * Returns a Builder with the default locale and with no 0297 * data model or pattern set. Either `setPattern()` 0298 * or `setDataModel()` has to be called before calling `build()`. 0299 * 0300 * @param status Input/output error code. 0301 * 0302 * @internal ICU 75 technology preview 0303 * @deprecated This API is for technology preview only. 0304 */ 0305 Builder(UErrorCode& status); 0306 /** 0307 * Destructor. 0308 * 0309 * @internal ICU 75 technology preview 0310 * @deprecated This API is for technology preview only. 0311 */ 0312 virtual ~Builder(); 0313 }; // class MessageFormatter::Builder 0314 0315 // TODO: Shouldn't be public; only used for testing 0316 /** 0317 * Returns a string consisting of the input with optional spaces removed. 0318 * 0319 * @return A normalized string representation of the input 0320 * 0321 * @internal ICU 75 technology preview 0322 * @deprecated This API is for technology preview only. 0323 */ 0324 const UnicodeString& getNormalizedPattern() const { return normalizedInput; } 0325 0326 private: 0327 friend class Builder; 0328 friend class MessageContext; 0329 0330 MessageFormatter(const MessageFormatter::Builder& builder, UErrorCode &status); 0331 0332 MessageFormatter() = delete; // default constructor not implemented 0333 0334 // Do not define default assignment operator 0335 const MessageFormatter &operator=(const MessageFormatter &) = delete; 0336 0337 ResolvedSelector resolveVariables(const Environment& env, const data_model::Operand&, MessageContext&, UErrorCode &) const; 0338 ResolvedSelector resolveVariables(const Environment& env, const data_model::Expression&, MessageContext&, UErrorCode &) const; 0339 0340 // Selection methods 0341 0342 // Takes a vector of FormattedPlaceholders 0343 void resolveSelectors(MessageContext&, const Environment& env, UErrorCode&, UVector&) const; 0344 // Takes a vector of vectors of strings (input) and a vector of PrioritizedVariants (output) 0345 void filterVariants(const UVector&, UVector&, UErrorCode&) const; 0346 // Takes a vector of vectors of strings (input) and a vector of PrioritizedVariants (input/output) 0347 void sortVariants(const UVector&, UVector&, UErrorCode&) const; 0348 // Takes a vector of strings (input) and a vector of strings (output) 0349 void matchSelectorKeys(const UVector&, MessageContext&, ResolvedSelector&& rv, UVector&, UErrorCode&) const; 0350 // Takes a vector of FormattedPlaceholders (input), 0351 // and a vector of vectors of strings (output) 0352 void resolvePreferences(MessageContext&, UVector&, UVector&, UErrorCode&) const; 0353 0354 // Formatting methods 0355 [[nodiscard]] FormattedPlaceholder formatLiteral(const data_model::Literal&) const; 0356 void formatPattern(MessageContext&, const Environment&, const data_model::Pattern&, UErrorCode&, UnicodeString&) const; 0357 // Formats a call to a formatting function 0358 // Dispatches on argument type 0359 [[nodiscard]] FormattedPlaceholder evalFormatterCall(FormattedPlaceholder&& argument, 0360 MessageContext& context, 0361 UErrorCode& status) const; 0362 // Dispatches on function name 0363 [[nodiscard]] FormattedPlaceholder evalFormatterCall(const FunctionName& functionName, 0364 FormattedPlaceholder&& argument, 0365 FunctionOptions&& options, 0366 MessageContext& context, 0367 UErrorCode& status) const; 0368 // Formats an expression that appears as a selector 0369 ResolvedSelector formatSelectorExpression(const Environment& env, const data_model::Expression&, MessageContext&, UErrorCode&) const; 0370 // Formats an expression that appears in a pattern or as the definition of a local variable 0371 [[nodiscard]] FormattedPlaceholder formatExpression(const Environment&, const data_model::Expression&, MessageContext&, UErrorCode&) const; 0372 [[nodiscard]] FunctionOptions resolveOptions(const Environment& env, const OptionMap&, MessageContext&, UErrorCode&) const; 0373 [[nodiscard]] FormattedPlaceholder formatOperand(const Environment&, const data_model::Operand&, MessageContext&, UErrorCode&) const; 0374 [[nodiscard]] FormattedPlaceholder evalArgument(const data_model::VariableName&, MessageContext&, UErrorCode&) const; 0375 void formatSelectors(MessageContext& context, const Environment& env, UErrorCode &status, UnicodeString& result) const; 0376 0377 // Function registry methods 0378 bool hasCustomMFFunctionRegistry() const { 0379 return (customMFFunctionRegistry != nullptr); 0380 } 0381 0382 // Precondition: custom function registry exists 0383 // Note: this is non-const because the values in the MFFunctionRegistry are mutable 0384 // (a FormatterFactory can have mutable state) 0385 const MFFunctionRegistry& getCustomMFFunctionRegistry() const; 0386 0387 bool isCustomFormatter(const FunctionName&) const; 0388 FormatterFactory* lookupFormatterFactory(const FunctionName&, UErrorCode& status) const; 0389 bool isBuiltInSelector(const FunctionName&) const; 0390 bool isBuiltInFormatter(const FunctionName&) const; 0391 bool isCustomSelector(const FunctionName&) const; 0392 const SelectorFactory* lookupSelectorFactory(MessageContext&, const FunctionName&, UErrorCode&) const; 0393 bool isSelector(const FunctionName& fn) const { return isBuiltInSelector(fn) || isCustomSelector(fn); } 0394 bool isFormatter(const FunctionName& fn) const { return isBuiltInFormatter(fn) || isCustomFormatter(fn); } 0395 const Formatter* lookupFormatter(const FunctionName&, UErrorCode&) const; 0396 0397 Selector* getSelector(MessageContext&, const FunctionName&, UErrorCode&) const; 0398 Formatter* getFormatter(const FunctionName&, UErrorCode&) const; 0399 bool getDefaultFormatterNameByType(const UnicodeString&, FunctionName&) const; 0400 0401 // Checking for resolution errors 0402 void checkDeclarations(MessageContext&, Environment*&, UErrorCode&) const; 0403 void check(MessageContext&, const Environment&, const data_model::Expression&, UErrorCode&) const; 0404 void check(MessageContext&, const Environment&, const data_model::Operand&, UErrorCode&) const; 0405 void check(MessageContext&, const Environment&, const OptionMap&, UErrorCode&) const; 0406 0407 void initErrors(UErrorCode&); 0408 void clearErrors() const; 0409 void cleanup() noexcept; 0410 0411 // The locale this MessageFormatter was created with 0412 /* const */ Locale locale; 0413 0414 // Registry for built-in functions 0415 MFFunctionRegistry standardMFFunctionRegistry; 0416 // Registry for custom functions; may be null if no custom registry supplied 0417 // Note: this is *not* owned by the MessageFormatter object 0418 // The reason for this choice is to have a non-destructive MessageFormatter::Builder, 0419 // while also not requiring the function registry to be deeply-copyable. Making the 0420 // function registry copyable would impose a requirement on any implementations 0421 // of the FormatterFactory and SelectorFactory interfaces to implement a custom 0422 // clone() method, which is necessary to avoid sharing between copies of the 0423 // function registry (and thus double-frees) 0424 // Not deeply immutable (the values in the function registry are mutable, 0425 // as a FormatterFactory can have mutable state 0426 const MFFunctionRegistry* customMFFunctionRegistry; 0427 0428 // Data model, representing the parsed message 0429 MFDataModel dataModel; 0430 0431 // Normalized version of the input string (optional whitespace removed) 0432 UnicodeString normalizedInput; 0433 0434 // Errors -- only used while parsing and checking for data model errors; then 0435 // the MessageContext keeps track of errors 0436 // Must be a raw pointer to avoid including the internal header file 0437 // defining StaticErrors 0438 // Owned by `this` 0439 StaticErrors* errors = nullptr; 0440 0441 // Error handling behavior. 0442 // If true, then formatting methods set their UErrorCode arguments 0443 // to signal MessageFormat errors, and no useful output is returned. 0444 // If false, then MessageFormat errors are not signaled and the 0445 // formatting methods return best-effort output. 0446 // The default is false. 0447 bool signalErrors = false; 0448 }; // class MessageFormatter 0449 0450 } // namespace message2 0451 0452 U_NAMESPACE_END 0453 0454 #endif // U_HIDE_DEPRECATED_API 0455 0456 #endif /* #if !UCONFIG_NO_MF2 */ 0457 0458 #endif /* #if !UCONFIG_NO_FORMATTING */ 0459 0460 #endif /* U_SHOW_CPLUSPLUS_API */ 0461 0462 #endif // MESSAGEFORMAT2_H 0463 0464 // eof
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|