ICU 78.1 78.1

messageformat2.h
Go to the documentation of this file.
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 #ifndef MESSAGEFORMAT2_H
7 #define MESSAGEFORMAT2_H
8
9 #if U_SHOW_CPLUSPLUS_API
10
11 #if !UCONFIG_NO_NORMALIZATION
12
13 #if !UCONFIG_NO_FORMATTING
14
15 #if !UCONFIG_NO_MF2
16
22 #include "unicode/messageformat2_arguments.h"
23 #include "unicode/messageformat2_data_model.h"
24 #include "unicode/messageformat2_function_registry.h"
25 #include "unicode/normalizer2.h"
26 #include "unicode/unistr.h"
27
28 #ifndef U_HIDE_DEPRECATED_API
29
30 U_NAMESPACE_BEGIN
31
32 namespace message2 {
33
34 class Environment;
35 class MessageContext;
36 class StaticErrors;
37 class InternalValue;
38
54 class U_I18N_API_CLASS MessageFormatter : public UObject {
55 // Note: This class does not currently inherit from the existing
56 // `Format` class.
57 public:
65 U_I18N_API MessageFormatter& operator=(MessageFormatter&&) noexcept;
72 U_I18N_API virtual ~MessageFormatter();
73
88 U_I18N_API UnicodeString formatToString(const MessageArguments& arguments, UErrorCode& status);
89
105 U_I18N_API FormattedMessage format(const MessageArguments& arguments, UErrorCode& status) const {
106 (void) arguments;
107 if (U_SUCCESS(status)) {
108 status = U_UNSUPPORTED_ERROR;
109 }
110 return FormattedMessage(status);
111 }
112
121 U_I18N_API const Locale& getLocale() const { return locale; }
122
132 U_I18N_API UnicodeString getPattern() const;
133
143 U_I18N_API const MFDataModel& getDataModel() const;
144
152 typedef enum UMFErrorHandlingBehavior {
159 U_MF_BEST_EFFORT = 0,
167 U_MF_STRICT
168 } UMFErrorHandlingBehavior;
169
176 class U_I18N_API_CLASS Builder : public UObject {
177 private:
178 friend class MessageFormatter;
179
180 // The pattern to be parsed to generate the formatted message
181 UnicodeString pattern;
182 bool hasPattern = false;
183 bool hasDataModel = false;
184 // The data model to be used to generate the formatted message
185 // Initialized either by `setDataModel()`, or by the parser
186 // through a call to `setPattern()`
187 MFDataModel dataModel;
188 // Normalized representation of the pattern;
189 // ignored if `setPattern()` wasn't called
190 UnicodeString normalizedInput;
191 // Errors (internal representation of parse errors)
192 // Ignored if `setPattern()` wasn't called
193 StaticErrors* errors;
194 Locale locale;
195 // Not owned
196 const MFFunctionRegistry* customMFFunctionRegistry;
197 // Error behavior; see comment in `MessageFormatter` class
198 bool signalErrors = false;
199
200 void clearState();
201 public:
211 U_I18N_API Builder& setLocale(const Locale& locale);
227 U_I18N_API Builder& setPattern(const UnicodeString& pattern,
228 UParseError& parseError,
229 UErrorCode& status);
243 U_I18N_API Builder& setFunctionRegistry(const MFFunctionRegistry& functionRegistry);
253 U_I18N_API Builder& setDataModel(MFDataModel&& dataModel);
283 U_I18N_API Builder& setErrorHandlingBehavior(UMFErrorHandlingBehavior type);
298 U_I18N_API MessageFormatter build(UErrorCode& status) const;
310 U_I18N_API Builder(UErrorCode& status);
317 U_I18N_API virtual ~Builder();
318 }; // class MessageFormatter::Builder
319
320 // TODO: Shouldn't be public; only used for testing
329 U_I18N_API const UnicodeString& getNormalizedPattern() const { return normalizedInput; }
330
331 private:
332 friend class Builder;
333 friend class Checker;
334 friend class MessageArguments;
335 friend class MessageContext;
336
337 MessageFormatter(const MessageFormatter::Builder& builder, UErrorCode &status);
338
339 MessageFormatter() = delete; // default constructor not implemented
340
341 // Do not define default assignment operator
342 const MessageFormatter &operator=(const MessageFormatter &) = delete;
343
344 // Selection methods
345
346 // Takes a vector of FormattedPlaceholders
347 void resolveSelectors(MessageContext&, const Environment& env, UErrorCode&, UVector&) const;
348 // Takes a vector of vectors of strings (input) and a vector of PrioritizedVariants (output)
349 void filterVariants(const UVector&, UVector&, UErrorCode&) const;
350 // Takes a vector of vectors of strings (input) and a vector of PrioritizedVariants (input/output)
351 void sortVariants(const UVector&, UVector&, UErrorCode&) const;
352 // Takes a vector of strings (input) and a vector of strings (output)
353 void matchSelectorKeys(const UVector&, MessageContext&, InternalValue* rv, UVector&, UErrorCode&) const;
354 // Takes a vector of FormattedPlaceholders (input),
355 // and a vector of vectors of strings (output)
356 void resolvePreferences(MessageContext&, UVector&, UVector&, UErrorCode&) const;
357
358 // Formatting methods
359
360 [[nodiscard]] FormattedPlaceholder formatLiteral(const UnicodeString&, const data_model::Literal&) const;
361 void formatPattern(MessageContext&, const Environment&, const data_model::Pattern&, UErrorCode&, UnicodeString&) const;
362 // Evaluates a function call
363 // Dispatches on argument type
364 [[nodiscard]] InternalValue* evalFunctionCall(FormattedPlaceholder&& argument,
365 MessageContext& context,
366 UErrorCode& status) const;
367 // Dispatches on function name
368 [[nodiscard]] InternalValue* evalFunctionCall(const FunctionName& functionName,
369 InternalValue* argument,
370 FunctionOptions&& options,
371 MessageContext& context,
372 UErrorCode& status) const;
373 // Formats an expression that appears in a pattern or as the definition of a local variable
374 [[nodiscard]] InternalValue* formatExpression(const UnicodeString&,
375 const Environment&,
376 const data_model::Expression&,
377 MessageContext&,
378 UErrorCode&) const;
379 [[nodiscard]] FunctionOptions resolveOptions(const Environment& env, const OptionMap&, MessageContext&, UErrorCode&) const;
380 [[nodiscard]] InternalValue* formatOperand(const UnicodeString&,
381 const Environment&,
382 const data_model::Operand&,
383 MessageContext&,
384 UErrorCode&) const;
385 [[nodiscard]] FormattedPlaceholder evalArgument(const UnicodeString&,
386 const data_model::VariableName&,
387 MessageContext&,
388 UErrorCode&) const;
389 void formatSelectors(MessageContext& context, const Environment& env, UErrorCode &status, UnicodeString& result) const;
390
391 // Function registry methods
392 bool hasCustomMFFunctionRegistry() const {
393 return (customMFFunctionRegistry != nullptr);
394 }
395
396 // Precondition: custom function registry exists
397 // Note: this is non-const because the values in the MFFunctionRegistry are mutable
398 // (a FormatterFactory can have mutable state)
399 const MFFunctionRegistry& getCustomMFFunctionRegistry() const;
400
401 bool isCustomFormatter(const FunctionName&) const;
402 FormatterFactory* lookupFormatterFactory(const FunctionName&, UErrorCode& status) const;
403 bool isBuiltInSelector(const FunctionName&) const;
404 bool isBuiltInFormatter(const FunctionName&) const;
405 bool isCustomSelector(const FunctionName&) const;
406 const SelectorFactory* lookupSelectorFactory(MessageContext&, const FunctionName&, UErrorCode&) const;
407 bool isSelector(const FunctionName& fn) const { return isBuiltInSelector(fn) || isCustomSelector(fn); }
408 bool isFormatter(const FunctionName& fn) const { return isBuiltInFormatter(fn) || isCustomFormatter(fn); }
409 const Formatter* lookupFormatter(const FunctionName&, UErrorCode&) const;
410
411 Selector* getSelector(MessageContext&, const FunctionName&, UErrorCode&) const;
412 Formatter* getFormatter(const FunctionName&, UErrorCode&) const;
413 bool getDefaultFormatterNameByType(const UnicodeString&, FunctionName&) const;
414
415 // Checking for resolution errors
416 void checkDeclarations(MessageContext&, Environment*&, UErrorCode&) const;
417 void check(MessageContext&, const Environment&, const data_model::Expression&, UErrorCode&) const;
418 void check(MessageContext&, const Environment&, const data_model::Operand&, UErrorCode&) const;
419 void check(MessageContext&, const Environment&, const OptionMap&, UErrorCode&) const;
420
421 void initErrors(UErrorCode&);
422 void clearErrors() const;
423 void cleanup() noexcept;
424
425 // The locale this MessageFormatter was created with
426 /* const */ Locale locale;
427
428 // Registry for built-in functions
429 MFFunctionRegistry standardMFFunctionRegistry;
430 // Registry for custom functions; may be null if no custom registry supplied
431 // Note: this is *not* owned by the MessageFormatter object
432 // The reason for this choice is to have a non-destructive MessageFormatter::Builder,
433 // while also not requiring the function registry to be deeply-copyable. Making the
434 // function registry copyable would impose a requirement on any implementations
435 // of the FormatterFactory and SelectorFactory interfaces to implement a custom
436 // clone() method, which is necessary to avoid sharing between copies of the
437 // function registry (and thus double-frees)
438 // Not deeply immutable (the values in the function registry are mutable,
439 // as a FormatterFactory can have mutable state
440 const MFFunctionRegistry* customMFFunctionRegistry;
441
442 // Data model, representing the parsed message
443 MFDataModel dataModel;
444
445 // Normalized version of the input string (optional whitespace removed)
446 UnicodeString normalizedInput;
447
448 // Errors -- only used while parsing and checking for data model errors; then
449 // the MessageContext keeps track of errors
450 // Must be a raw pointer to avoid including the internal header file
451 // defining StaticErrors
452 // Owned by `this`
453 StaticErrors* errors = nullptr;
454
455 // Error handling behavior.
456 // If true, then formatting methods set their UErrorCode arguments
457 // to signal MessageFormat errors, and no useful output is returned.
458 // If false, then MessageFormat errors are not signaled and the
459 // formatting methods return best-effort output.
460 // The default is false.
461 bool signalErrors = false;
462
463 }; // class MessageFormatter
464
465 } // namespace message2
466
467 U_NAMESPACE_END
468
469 #endif // U_HIDE_DEPRECATED_API
470
471 #endif /* #if !UCONFIG_NO_MF2 */
472
473 #endif /* #if !UCONFIG_NO_FORMATTING */
474
475 #endif /* #if !UCONFIG_NO_NORMALIZATION */
476
477 #endif /* U_SHOW_CPLUSPLUS_API */
478
479 #endif // MESSAGEFORMAT2_H
480
481 // eof
icu::Locale
A Locale object represents a specific geographical, political, or cultural region.
Definition: locid.h:198
icu::UObject
UObject is the common ICU "boilerplate" class.
Definition: uobject.h:222
icu::UnicodeString
UnicodeString is a string class that stores Unicode characters directly and provides similar function...
Definition: unistr.h:303
icu::message2::FormattedMessage
Not yet implemented: The result of a message formatting operation.
Definition: messageformat2_formattable.h:885
icu::message2::FormattedPlaceholder
A FormattablePlaceholder encapsulates an input value (a message2::Formattable) together with an optio...
Definition: messageformat2_formattable.h:691
icu::message2::FunctionOptions
Structure encapsulating named options passed to a custom selector or formatter.
Definition: messageformat2_formattable.h:490
icu::message2::MFFunctionRegistry
Defines mappings from names of formatters and selectors to functions implementing them.
Definition: messageformat2_function_registry.h:119
icu::message2::MessageArguments
The MessageArguments class represents the named arguments to a message.
Definition: messageformat2_arguments.h:47
icu::message2::MessageFormatter::Builder
The mutable Builder class allows each part of the MessageFormatter to be initialized separately; call...
Definition: messageformat2.h:176
icu::message2::MessageFormatter::Builder::setPattern
U_I18N_API Builder & setPattern(const UnicodeString &pattern, UParseError &parseError, UErrorCode &status)
Sets the pattern (contents of the message) and parses it into a data model.
icu::message2::MessageFormatter::Builder::setErrorHandlingBehavior
U_I18N_API Builder & setErrorHandlingBehavior(UMFErrorHandlingBehavior type)
Set the error handling behavior for this formatter.
icu::message2::MessageFormatter::Builder::setFunctionRegistry
U_I18N_API Builder & setFunctionRegistry(const MFFunctionRegistry &functionRegistry)
Sets a custom function registry.
icu::message2::MessageFormatter::Builder::setDataModel
U_I18N_API Builder & setDataModel(MFDataModel &&dataModel)
Sets a data model.
icu::message2::MessageFormatter::Builder::setLocale
U_I18N_API Builder & setLocale(const Locale &locale)
Sets the locale to use for formatting.
icu::message2::MessageFormatter::Builder::~Builder
virtual U_I18N_API ~Builder()
Destructor.
icu::message2::MessageFormatter::Builder::Builder
U_I18N_API Builder(UErrorCode &status)
Default constructor.
icu::message2::MessageFormatter::Builder::build
U_I18N_API MessageFormatter build(UErrorCode &status) const
Constructs a new immutable MessageFormatter using the pattern or data model that was previously set,...
icu::message2::MessageFormatter
Definition: messageformat2.h:54
icu::message2::MessageFormatter::getNormalizedPattern
U_I18N_API const UnicodeString & getNormalizedPattern() const
Returns a string consisting of the input with optional spaces removed.
Definition: messageformat2.h:329
icu::message2::MessageFormatter::getDataModel
U_I18N_API const MFDataModel & getDataModel() const
Accesses the data model referred to by this MessageFormatter object.
icu::message2::MessageFormatter::operator=
U_I18N_API MessageFormatter & operator=(MessageFormatter &&) noexcept
Move assignment operator: The source MessageFormatter will be left in a valid but undefined state.
icu::message2::MessageFormatter::getLocale
U_I18N_API const Locale & getLocale() const
Accesses the locale that this MessageFormatter object was created with.
Definition: messageformat2.h:121
icu::message2::MessageFormatter::getPattern
U_I18N_API UnicodeString getPattern() const
Serializes the data model as a string in MessageFormat 2.0 syntax.
icu::message2::MessageFormatter::UMFErrorHandlingBehavior
UMFErrorHandlingBehavior
Used in conjunction with the MessageFormatter::Builder::setErrorHandlingBehavior() method.
Definition: messageformat2.h:152
icu::message2::data_model::Expression
The Expression class corresponds to the expression nonterminal in the MessageFormat 2 grammar and the...
Definition: messageformat2_data_model.h:1161
icu::message2::data_model::Literal
The Literal class corresponds to the literal nonterminal in the MessageFormat 2 grammar,...
Definition: messageformat2_data_model.h:78
icu::message2::data_model::MFDataModel
The MFDataModel class describes a parsed representation of the text of a message.
Definition: messageformat2_data_model.h:2095
icu::message2::data_model::Operand
The Operand class corresponds to the operand nonterminal in the MessageFormat 2 grammar,...
Definition: messageformat2_data_model.h:215
icu::message2::data_model::Pattern
A Pattern is a sequence of formattable parts.
Definition: messageformat2_data_model.h:1539
messageformat2_arguments.h
C++ API: Formats messages using the draft MessageFormat 2.0.
normalizer2.h
C++ API: New API for Unicode Normalization.
UParseError
A UParseError struct is used to returned detailed information about parsing errors.
Definition: parseerr.h:58
unistr.h
C++ API: Unicode String.
utypes.h
Basic definitions for ICU, for both C and C++ APIs.
UErrorCode
UErrorCode
Standard ICU4C error code type, a substitute for exceptions.
Definition: utypes.h:509
U_UNSUPPORTED_ERROR
@ U_UNSUPPORTED_ERROR
Requested operation not supported in current context.
Definition: utypes.h:561
U_SUCCESS
#define U_SUCCESS(x)
Does the error code indicate success?
Definition: utypes.h:822
U_I18N_API_CLASS
#define U_I18N_API_CLASS
Set to export library symbols from inside the i18n library, and to import them from outside,...
Definition: utypes.h:457
U_I18N_API
#define U_I18N_API
Set to export library symbols from inside the i18n library, and to import them from outside.
Definition: utypes.h:316