messageformat2_function_registry.h (18504B)
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_FUNCTION_REGISTRY_H 7 #define MESSAGEFORMAT2_FUNCTION_REGISTRY_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 17 #include "unicode/messageformat2_data_model_names.h" 18 #include "unicode/messageformat2_formattable.h" 19 20 #ifndef U_HIDE_DEPRECATED_API 21 22 #include <map> 23 24 U_NAMESPACE_BEGIN 25 26 class Hashtable; 27 class UVector; 28 29 namespace message2 { 30 31 using namespace data_model; 32 33 /** 34 * Interface that factory classes for creating formatters must implement. 35 * 36 * @internal ICU 75 technology preview 37 * @deprecated This API is for technology preview only. 38 */ 39 class U_I18N_API FormatterFactory : public UObject { 40 // TODO: the coding guidelines say that interface classes 41 // shouldn't inherit from UObject, but if I change it so these 42 // classes don't, and the individual formatter factory classes 43 // inherit from public FormatterFactory, public UObject, then 44 // memory leaks ensue 45 public: 46 /** 47 * Constructs a new formatter object. This method is not const; 48 * formatter factories with local state may be defined. 49 * 50 * @param locale Locale to be used by the formatter. 51 * @param status Input/output error code. 52 * @return The new Formatter, which is non-null if U_SUCCESS(status). 53 * 54 * @internal ICU 75 technology preview 55 * @deprecated This API is for technology preview only. 56 */ 57 virtual Formatter* createFormatter(const Locale& locale, UErrorCode& status) = 0; 58 /** 59 * Destructor. 60 * 61 * @internal ICU 75 technology preview 62 * @deprecated This API is for technology preview only. 63 */ 64 virtual ~FormatterFactory(); 65 /** 66 * Copy constructor. 67 * 68 * @internal ICU 75 technology preview 69 * @deprecated This API is for technology preview only. 70 */ 71 FormatterFactory& operator=(const FormatterFactory&) = delete; 72 }; // class FormatterFactory 73 74 /** 75 * Interface that factory classes for creating selectors must implement. 76 * 77 * @internal ICU 75 technology preview 78 * @deprecated This API is for technology preview only. 79 */ 80 class U_I18N_API SelectorFactory : public UObject { 81 public: 82 /** 83 * Constructs a new selector object. 84 * 85 * @param locale Locale to be used by the selector. 86 * @param status Input/output error code. 87 * @return The new selector, which is non-null if U_SUCCESS(status). 88 * 89 * @internal ICU 75 technology preview 90 * @deprecated This API is for technology preview only. 91 */ 92 virtual Selector* createSelector(const Locale& locale, UErrorCode& status) const = 0; 93 /** 94 * Destructor. 95 * 96 * @internal ICU 75 technology preview 97 * @deprecated This API is for technology preview only. 98 */ 99 virtual ~SelectorFactory(); 100 /** 101 * Copy constructor. 102 * 103 * @internal ICU 75 technology preview 104 * @deprecated This API is for technology preview only. 105 */ 106 SelectorFactory& operator=(const SelectorFactory&) = delete; 107 }; // class SelectorFactory 108 109 /** 110 * Defines mappings from names of formatters and selectors to functions implementing them. 111 * The required set of formatter and selector functions is defined in the spec. Users can 112 * also define custom formatter and selector functions. 113 * 114 * `MFFunctionRegistry` is immutable and movable. It is not copyable. 115 * 116 * @internal ICU 75 technology preview 117 * @deprecated This API is for technology preview only. 118 */ 119 class U_I18N_API MFFunctionRegistry : public UObject { 120 private: 121 122 using FormatterMap = Hashtable; // Map from stringified function names to FormatterFactory* 123 using SelectorMap = Hashtable; // Map from stringified function names to SelectorFactory* 124 125 public: 126 /** 127 * Looks up a formatter factory by the name of the formatter. The result is non-const, 128 * since formatter factories may have local state. Returns the result by pointer 129 * rather than by reference since it can fail. 130 * 131 * @param formatterName Name of the desired formatter. 132 * @return A pointer to the `FormatterFactory` registered under `formatterName`, or null 133 * if no formatter was registered under that name. The pointer is not owned 134 * by the caller. 135 * 136 * @internal ICU 75 technology preview 137 * @deprecated This API is for technology preview only. 138 */ 139 FormatterFactory* getFormatter(const FunctionName& formatterName) const; 140 /** 141 * Looks up a selector factory by the name of the selector. (This returns the result by pointer 142 * rather than by reference since `FormatterFactory` is an abstract class.) 143 * 144 * @param selectorName Name of the desired selector. 145 * @return A pointer to the `SelectorFactory` registered under `selectorName`, or null 146 * if no formatter was registered under that name. 147 * 148 * @internal ICU 75 technology preview 149 * @deprecated This API is for technology preview only. 150 */ 151 const SelectorFactory* getSelector(const FunctionName& selectorName) const; 152 /** 153 * Looks up a formatter factory by a type tag. This method gets the name of the default formatter registered 154 * for that type. If no formatter was explicitly registered for this type, it returns false. 155 * 156 * @param formatterType Type tag for the desired `FormattableObject` type to be formatted. 157 * @param name Output parameter; initialized to the name of the default formatter for `formatterType` 158 * if one has been registered. Its value is undefined otherwise. 159 * @return True if and only if the function registry contains a default formatter for `formatterType`. 160 * If the return value is false, then the value of `name` is undefined. 161 * 162 * @internal ICU 75 technology preview 163 * @deprecated This API is for technology preview only. 164 */ 165 UBool getDefaultFormatterNameByType(const UnicodeString& formatterType, FunctionName& name) const; 166 /** 167 * The mutable Builder class allows each formatter and selector factory 168 * to be initialized separately; calling its `build()` method yields an 169 * immutable MFFunctionRegistry object. 170 * 171 * Builder is not copyable or movable. 172 * 173 * @internal ICU 75 technology preview 174 * @deprecated This API is for technology preview only. 175 */ 176 class U_I18N_API Builder : public UObject { 177 private: 178 // Must use raw pointers to avoid instantiating `LocalPointer` on an internal type 179 FormatterMap* formatters; 180 SelectorMap* selectors; 181 Hashtable* formattersByType; 182 183 // Do not define copy constructor/assignment operator 184 Builder& operator=(const Builder&) = delete; 185 Builder(const Builder&) = delete; 186 187 public: 188 /* 189 Notes about `adoptFormatter()`'s type signature: 190 191 Alternative considered: take a non-owned FormatterFactory* 192 This is unsafe. 193 194 Alternative considered: take a FormatterFactory& 195 This requires getFormatter() to cast the reference to a pointer, 196 as it must return an unowned FormatterFactory* since it can fail. 197 That is also unsafe, since the caller could delete the pointer. 198 199 The "TemperatureFormatter" test from the previous ICU4J version doesn't work now, 200 as it only works if the `formatterFactory` argument is non-owned. 201 If registering a non-owned FormatterFactory is desirable, this could 202 be re-thought. 203 */ 204 /** 205 * Registers a formatter factory to a given formatter name. 206 * 207 * @param formatterName Name of the formatter being registered. 208 * @param formatterFactory A pointer to a FormatterFactory object to use 209 * for creating `formatterName` formatters. This argument is adopted. 210 * @param errorCode Input/output error code 211 * @return A reference to the builder. 212 * 213 * @internal ICU 75 technology preview 214 * @deprecated This API is for technology preview only. 215 */ 216 Builder& adoptFormatter(const data_model::FunctionName& formatterName, FormatterFactory* formatterFactory, UErrorCode& errorCode); 217 /** 218 * Registers a formatter factory to a given type tag. 219 * (See `FormattableObject` for details on type tags.) 220 * 221 * @param type Tag for objects to be formatted with this formatter. 222 * @param functionName A reference to the name of the function to use for 223 * creating formatters for `formatterType` objects. 224 * @param errorCode Input/output error code 225 * @return A reference to the builder. 226 * 227 * @internal ICU 75 technology preview 228 * @deprecated This API is for technology preview only. 229 */ 230 Builder& setDefaultFormatterNameByType(const UnicodeString& type, const data_model::FunctionName& functionName, UErrorCode& errorCode); 231 232 /** 233 * Registers a selector factory to a given selector name. Adopts `selectorFactory`. 234 * 235 * @param selectorName Name of the selector being registered. 236 * @param selectorFactory A SelectorFactory object to use for creating `selectorName` 237 * selectors. 238 * @param errorCode Input/output error code 239 * @return A reference to the builder. 240 * 241 * @internal ICU 75 technology preview 242 * @deprecated This API is for technology preview only. 243 */ 244 Builder& adoptSelector(const data_model::FunctionName& selectorName, SelectorFactory* selectorFactory, UErrorCode& errorCode); 245 /** 246 * Creates an immutable `MFFunctionRegistry` object with the selectors and formatters 247 * that were previously registered. The builder cannot be used after this call. 248 * The `build()` method is destructive to avoid the need for a deep copy of the 249 * `FormatterFactory` and `SelectorFactory` objects (this would be necessary because 250 * `FormatterFactory` can have mutable state), which in turn would require implementors 251 * of those interfaces to implement a `clone()` method. 252 * 253 * @return The new MFFunctionRegistry 254 * 255 * @internal ICU 75 technology preview 256 * @deprecated This API is for technology preview only. 257 */ 258 MFFunctionRegistry build(); 259 /** 260 * Default constructor. 261 * Returns a Builder with no functions registered. 262 * 263 * @param errorCode Input/output error code 264 * 265 * @internal ICU 75 technology preview 266 * @deprecated This API is for technology preview only. 267 */ 268 Builder(UErrorCode& errorCode); 269 /** 270 * Destructor. 271 * 272 * @internal ICU 75 technology preview 273 * @deprecated This API is for technology preview only. 274 */ 275 virtual ~Builder(); 276 }; // class MFFunctionRegistry::Builder 277 278 /** 279 * Move assignment operator: 280 * The source MFFunctionRegistry will be left in a valid but undefined state. 281 * 282 * @internal ICU 75 technology preview 283 * @deprecated This API is for technology preview only. 284 */ 285 MFFunctionRegistry& operator=(MFFunctionRegistry&&) noexcept; 286 /** 287 * Move constructor: 288 * The source MFFunctionRegistry will be left in a valid but undefined state. 289 * 290 * @internal ICU 75 technology preview 291 * @deprecated This API is for technology preview only. 292 */ 293 MFFunctionRegistry(MFFunctionRegistry&& other) { *this = std::move(other); } 294 /** 295 * Destructor. 296 * 297 * @internal ICU 75 technology preview 298 * @deprecated This API is for technology preview only. 299 */ 300 virtual ~MFFunctionRegistry(); 301 302 private: 303 friend class MessageContext; 304 friend class MessageFormatter; 305 306 // Do not define copy constructor or copy assignment operator 307 MFFunctionRegistry& operator=(const MFFunctionRegistry&) = delete; 308 MFFunctionRegistry(const MFFunctionRegistry&) = delete; 309 310 MFFunctionRegistry(FormatterMap* f, SelectorMap* s, Hashtable* byType); 311 312 MFFunctionRegistry() {} 313 314 // Debugging; should only be called on a function registry with 315 // all the standard functions registered 316 void checkFormatter(const char*) const; 317 void checkSelector(const char*) const; 318 void checkStandard() const; 319 320 bool hasFormatter(const data_model::FunctionName& f) const; 321 bool hasSelector(const data_model::FunctionName& s) const; 322 void cleanup() noexcept; 323 324 // Must use raw pointers to avoid instantiating `LocalPointer` on an internal type 325 FormatterMap* formatters = nullptr; 326 SelectorMap* selectors = nullptr; 327 // Mapping from strings (type tags) to FunctionNames 328 Hashtable* formattersByType = nullptr; 329 }; // class MFFunctionRegistry 330 331 /** 332 * Interface that formatter classes must implement. 333 * 334 * @internal ICU 75 technology preview 335 * @deprecated This API is for technology preview only. 336 */ 337 class U_I18N_API Formatter : public UObject { 338 public: 339 /** 340 * Formats the input passed in `context` by setting an output using one of the 341 * `FormattingContext` methods or indicating an error. 342 * 343 * @param toFormat Placeholder, including a source formattable value and possibly 344 * the output of a previous formatter applied to it; see 345 * `message2::FormattedPlaceholder` for details. Passed by move. 346 * @param options The named function options. Passed by move 347 * @param status Input/output error code. Should not be set directly by the 348 * custom formatter, which should use `FormattingContext::setFormattingWarning()` 349 * to signal errors. The custom formatter may pass `status` to other ICU functions 350 * that can signal errors using this mechanism. 351 * 352 * @return The formatted value. 353 * 354 * @internal ICU 75 technology preview 355 * @deprecated This API is for technology preview only. 356 */ 357 virtual FormattedPlaceholder format(FormattedPlaceholder&& toFormat, 358 FunctionOptions&& options, 359 UErrorCode& status) const = 0; 360 /** 361 * Destructor. 362 * 363 * @internal ICU 75 technology preview 364 * @deprecated This API is for technology preview only. 365 */ 366 virtual ~Formatter(); 367 }; // class Formatter 368 369 /** 370 * Interface that selector classes must implement. 371 * 372 * @internal ICU 75 technology preview 373 * @deprecated This API is for technology preview only. 374 */ 375 class U_I18N_API Selector : public UObject { 376 public: 377 /** 378 * Compares the input to an array of keys, and returns an array of matching 379 * keys sorted by preference. 380 * 381 * @param toFormat The unnamed function argument; passed by move. 382 * @param options A reference to the named function options. 383 * @param keys An array of strings that are compared to the input 384 * (`context.getFormattableInput()`) in an implementation-specific way. 385 * @param keysLen The length of `keys`. 386 * @param prefs An array of strings with length `keysLen`. The contents of 387 * the array is undefined. `selectKey()` should set the contents 388 * of `prefs` to a subset of `keys`, with the best match placed at the lowest index. 389 * @param prefsLen A reference that `selectKey()` should set to the length of `prefs`, 390 * which must be less than or equal to `keysLen`. 391 * @param status Input/output error code. Should not be set directly by the 392 * custom selector, which should use `FormattingContext::setSelectorError()` 393 * to signal errors. The custom selector may pass `status` to other ICU functions 394 * that can signal errors using this mechanism. 395 * 396 * @internal ICU 75 technology preview 397 * @deprecated This API is for technology preview only. 398 */ 399 virtual void selectKey(FormattedPlaceholder&& toFormat, 400 FunctionOptions&& options, 401 const UnicodeString* keys, 402 int32_t keysLen, 403 UnicodeString* prefs, 404 int32_t& prefsLen, 405 UErrorCode& status) const = 0; 406 // Note: This takes array arguments because the internal MessageFormat code has to 407 // call this method, and can't include any code that constructs std::vectors. 408 /** 409 * Destructor. 410 * 411 * @internal ICU 75 technology preview 412 * @deprecated This API is for technology preview only. 413 */ 414 virtual ~Selector(); 415 }; // class Selector 416 417 } // namespace message2 418 419 U_NAMESPACE_END 420 421 #endif // U_HIDE_DEPRECATED_API 422 423 #endif /* #if !UCONFIG_NO_MF2 */ 424 425 #endif /* #if !UCONFIG_NO_FORMATTING */ 426 427 #endif /* #if !UCONFIG_NO_NORMALIZATION */ 428 429 #endif /* U_SHOW_CPLUSPLUS_API */ 430 431 #endif // MESSAGEFORMAT2_FUNCTION_REGISTRY_H 432 433 // eof