|
|
|||
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 MESSAGEFORMAT_DATA_MODEL_H 0007 #define MESSAGEFORMAT_DATA_MODEL_H 0008 0009 #if U_SHOW_CPLUSPLUS_API 0010 0011 #if !UCONFIG_NO_FORMATTING 0012 0013 #if !UCONFIG_NO_MF2 0014 0015 #include "unicode/localpointer.h" 0016 #include "unicode/messageformat2_data_model_names.h" 0017 0018 #ifndef U_HIDE_DEPRECATED_API 0019 0020 #include <algorithm> 0021 #include <cstddef> 0022 #include <iterator> 0023 #include <optional> 0024 #include <variant> 0025 #include <vector> 0026 0027 U_NAMESPACE_BEGIN 0028 0029 class UVector; 0030 0031 // Helpers 0032 0033 // Note: this _must_ be declared `inline` or else gcc will generate code 0034 // for its instantiations, which needs to be avoided because it returns 0035 // a std::vector 0036 template<typename T> 0037 static inline std::vector<T> toStdVector(const T* arr, int32_t len) { 0038 std::vector<T> result; 0039 for (int32_t i = 0; i < len; i++) { 0040 result.push_back(arr[i]); 0041 } 0042 return result; 0043 } 0044 0045 #if defined(U_REAL_MSVC) 0046 #pragma warning(push) 0047 // Ignore warning 4251 as these templates are instantiated later in this file, 0048 // after the classes used to instantiate them have been defined. 0049 #pragma warning(disable: 4251) 0050 #endif 0051 0052 namespace message2 { 0053 class Checker; 0054 class MFDataModel; 0055 class MessageFormatter; 0056 class Parser; 0057 class Serializer; 0058 0059 0060 namespace data_model { 0061 class Binding; 0062 class Literal; 0063 class Operator; 0064 0065 /** 0066 * The `Literal` class corresponds to the `literal` nonterminal in the MessageFormat 2 grammar, 0067 * https://github.com/unicode-org/message-format-wg/blob/main/spec/message.abnf and the 0068 * `Literal` interface defined in 0069 * // https://github.com/unicode-org/message-format-wg/blob/main/spec/data-model.md#expressions 0070 * 0071 * `Literal` is immutable, copyable and movable. 0072 * 0073 * @internal ICU 75 technology preview 0074 * @deprecated This API is for technology preview only. 0075 */ 0076 class U_I18N_API Literal : public UObject { 0077 public: 0078 /** 0079 * Returns the quoted representation of this literal (enclosed in '|' characters) 0080 * 0081 * @return A string representation of the literal enclosed in quote characters. 0082 * 0083 * @internal ICU 75 technology preview 0084 * @deprecated This API is for technology preview only. 0085 */ 0086 UnicodeString quoted() const; 0087 /** 0088 * Returns the parsed string contents of this literal. 0089 * 0090 * @return A string representation of this literal. 0091 * 0092 * @internal ICU 75 technology preview 0093 * @deprecated This API is for technology preview only. 0094 */ 0095 const UnicodeString& unquoted() const; 0096 /** 0097 * Determines if this literal appeared as a quoted literal in the message. 0098 * 0099 * @return true if and only if this literal appeared as a quoted literal in the 0100 * message. 0101 * 0102 * @internal ICU 75 technology preview 0103 * @deprecated This API is for technology preview only. 0104 */ 0105 UBool isQuoted() const { return thisIsQuoted; } 0106 /** 0107 * Literal constructor. 0108 * 0109 * @param q True if and only if this literal was parsed with the `quoted` nonterminal 0110 * (appeared enclosed in '|' characters in the message text). 0111 * @param s The string contents of this literal; escape sequences are assumed to have 0112 * been interpreted already. 0113 * 0114 * @internal ICU 75 technology preview 0115 * @deprecated This API is for technology preview only. 0116 */ 0117 Literal(UBool q, const UnicodeString& s) : thisIsQuoted(q), contents(s) {} 0118 /** 0119 * Copy constructor. 0120 * 0121 * @internal ICU 75 technology preview 0122 * @deprecated This API is for technology preview only. 0123 */ 0124 Literal(const Literal& other) : thisIsQuoted(other.thisIsQuoted), contents(other.contents) {} 0125 /** 0126 * Non-member swap function. 0127 * @param l1 will get l2's contents 0128 * @param l2 will get l1's contents 0129 * 0130 * @internal ICU 75 technology preview 0131 * @deprecated This API is for technology preview only. 0132 */ 0133 friend inline void swap(Literal& l1, Literal& l2) noexcept { 0134 using std::swap; 0135 0136 swap(l1.thisIsQuoted, l2.thisIsQuoted); 0137 swap(l1.contents, l2.contents); 0138 } 0139 /** 0140 * Assignment operator. 0141 * 0142 * @internal ICU 75 technology preview 0143 * @deprecated This API is for technology preview only. 0144 */ 0145 Literal& operator=(Literal) noexcept; 0146 /** 0147 * Default constructor. 0148 * Puts the Literal into a valid but undefined state. 0149 * 0150 * @internal ICU 75 technology preview 0151 * @deprecated This API is for technology preview only. 0152 */ 0153 Literal() = default; 0154 /** 0155 * Less than operator. Compares `this.stringContents()` with 0156 * `other.stringContents()`. This method is used in representing 0157 * the mapping from key lists to patterns in a message with variants, 0158 * and is not expected to be useful otherwise. 0159 * 0160 * @param other The Literal to compare to this one. 0161 * @return true if the parsed string corresponding to this `Literal` 0162 * is less than the parsed string corresponding to the other `Literal` 0163 * (according to `UnicodeString`'s less-than operator). 0164 * Returns false otherwise. 0165 * 0166 * @internal ICU 75 technology preview 0167 * @deprecated This API is for technology preview only. 0168 */ 0169 bool operator<(const Literal& other) const; 0170 /** 0171 * Equality operator. Compares `this.stringContents()` with 0172 * `other.stringContents()`. This method is used in representing 0173 * the mapping from key lists to patterns in a message with variants, 0174 * and is not expected to be useful otherwise. 0175 * 0176 * @param other The Literal to compare to this one. 0177 * @return true if the parsed string corresponding to this `Literal` 0178 * equals the parsed string corresponding to the other `Literal` 0179 * (according to `UnicodeString`'s equality operator). 0180 * Returns false otherwise. 0181 * 0182 * @internal ICU 75 technology preview 0183 * @deprecated This API is for technology preview only. 0184 */ 0185 bool operator==(const Literal& other) const; 0186 /** 0187 * Destructor. 0188 * 0189 * @internal ICU 75 technology preview 0190 * @deprecated This API is for technology preview only. 0191 */ 0192 virtual ~Literal(); 0193 0194 private: 0195 /* const */ bool thisIsQuoted = false; 0196 /* const */ UnicodeString contents; 0197 }; 0198 } // namespace data_model 0199 } // namespace message2 0200 0201 /// @cond DOXYGEN_IGNORE 0202 // Export an explicit template instantiation of the LocalPointer that is used as a 0203 // data member of various MFDataModel classes. 0204 // (When building DLLs for Windows this is required.) 0205 // (See measunit_impl.h, datefmt.h, collationiterator.h, erarules.h and others 0206 // for similar examples.) 0207 #if U_PF_WINDOWS <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN 0208 template class U_I18N_API LocalPointerBase<message2::data_model::Literal>; 0209 template class U_I18N_API LocalArray<message2::data_model::Literal>; 0210 #endif 0211 #if defined(U_REAL_MSVC) 0212 #pragma warning(pop) 0213 #endif 0214 /// @endcond 0215 0216 U_NAMESPACE_END 0217 0218 /// @cond DOXYGEN_IGNORE 0219 // Export an explicit template instantiation of the std::variants and std::optionals 0220 // that are used as a data member of various MFDataModel classes. 0221 // (When building DLLs for Windows this is required.) 0222 // (See measunit_impl.h, datefmt.h, collationiterator.h, erarules.h and others 0223 // for similar examples.) 0224 #if U_PF_WINDOWS <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN 0225 #if defined(U_REAL_MSVC) && defined(_MSVC_STL_VERSION) 0226 struct U_I18N_API std::_Nontrivial_dummy_type; 0227 template class U_I18N_API std::_Variant_storage_<false, icu::UnicodeString, icu::message2::data_model::Literal>; 0228 #endif 0229 template class U_I18N_API std::variant<icu::UnicodeString, icu::message2::data_model::Literal>; 0230 template class U_I18N_API std::optional<std::variant<icu::UnicodeString, icu::message2::data_model::Literal>>; 0231 template class U_I18N_API std::optional<icu::message2::data_model::Literal>; 0232 #endif 0233 /// @endcond 0234 0235 U_NAMESPACE_BEGIN 0236 0237 namespace message2 { 0238 namespace data_model { 0239 0240 /** 0241 * The `Operand` class corresponds to the `operand` nonterminal in the MessageFormat 2 grammar, 0242 * https://github.com/unicode-org/message-format-wg/blob/main/spec/message.abnf . 0243 * It represents a `Literal | VariableRef` -- see the `operand?` field of the `FunctionRef` 0244 * interface defined at: 0245 * https://github.com/unicode-org/message-format-wg/blob/main/spec/data-model.md#expressions 0246 * with the difference that it can also represent a null operand (the absent operand in an 0247 * `annotation` with no operand). 0248 * 0249 * `Operand` is immutable and is copyable and movable. 0250 * 0251 * @internal ICU 75 technology preview 0252 * @deprecated This API is for technology preview only. 0253 */ 0254 class U_I18N_API Operand : public UObject { 0255 public: 0256 /** 0257 * Determines if this operand represents a variable. 0258 * 0259 * @return True if and only if the operand is a variable. 0260 * 0261 * @internal ICU 75 technology preview 0262 * @deprecated This API is for technology preview only. 0263 */ 0264 UBool isVariable() const; 0265 /** 0266 * Determines if this operand represents a literal. 0267 * 0268 * @return True if and only if the operand is a literal. 0269 * 0270 * @internal ICU 75 technology preview 0271 * @deprecated This API is for technology preview only. 0272 */ 0273 UBool isLiteral() const; 0274 /** 0275 * Determines if this operand is the null operand. 0276 * 0277 * @return True if and only if the operand is the null operand. 0278 * 0279 * @internal ICU 75 technology preview 0280 * @deprecated This API is for technology preview only. 0281 */ 0282 virtual UBool isNull() const; 0283 /** 0284 * Returns a reference to this operand's variable name. 0285 * Precondition: isVariable() 0286 * 0287 * @return A reference to the name of the variable 0288 * 0289 * @internal ICU 75 technology preview 0290 * @deprecated This API is for technology preview only. 0291 */ 0292 const UnicodeString& asVariable() const; 0293 /** 0294 * Returns a reference to this operand's literal contents. 0295 * Precondition: isLiteral() 0296 * 0297 * @return A reference to the literal 0298 * 0299 * @internal ICU 75 technology preview 0300 * @deprecated This API is for technology preview only. 0301 */ 0302 const Literal& asLiteral() const; 0303 /** 0304 * Default constructor. 0305 * Creates a null Operand. 0306 * 0307 * @internal ICU 75 technology preview 0308 * @deprecated This API is for technology preview only. 0309 */ 0310 Operand() : contents(std::nullopt) {} 0311 /** 0312 * Variable operand constructor. 0313 * 0314 * @param v The variable name; an operand corresponding 0315 * to a reference to `v` is returned. 0316 * 0317 * @internal ICU 75 technology preview 0318 * @deprecated This API is for technology preview only. 0319 */ 0320 explicit Operand(const UnicodeString& v) : contents(VariableName(v)) {} 0321 /** 0322 * Literal operand constructor. 0323 * 0324 * @param l The literal to use for this operand; an operand 0325 * corresponding to `l` is returned. 0326 * 0327 * @internal ICU 75 technology preview 0328 * @deprecated This API is for technology preview only. 0329 */ 0330 explicit Operand(const Literal& l) : contents(l) {} 0331 /** 0332 * Non-member swap function. 0333 * @param o1 will get o2's contents 0334 * @param o2 will get o1's contents 0335 * 0336 * @internal ICU 75 technology preview 0337 * @deprecated This API is for technology preview only. 0338 */ 0339 friend inline void swap(Operand& o1, Operand& o2) noexcept { 0340 using std::swap; 0341 (void) o1; 0342 (void) o2; 0343 swap(o1.contents, o2.contents); 0344 } 0345 /** 0346 * Assignment operator. 0347 * 0348 * @internal ICU 75 technology preview 0349 * @deprecated This API is for technology preview only. 0350 */ 0351 virtual Operand& operator=(Operand) noexcept; 0352 /** 0353 * Copy constructor. 0354 * 0355 * @internal ICU 75 technology preview 0356 * @deprecated This API is for technology preview only. 0357 */ 0358 Operand(const Operand&); 0359 /** 0360 * Destructor. 0361 * 0362 * @internal ICU 75 technology preview 0363 * @deprecated This API is for technology preview only. 0364 */ 0365 virtual ~Operand(); 0366 private: 0367 std::optional<std::variant<VariableName, Literal>> contents; 0368 }; // class Operand 0369 0370 /** 0371 * The `Key` class corresponds to the `key` nonterminal in the MessageFormat 2 grammar, 0372 * https://github.com/unicode-org/message-format-wg/blob/main/spec/message.abnf . 0373 * It also corresponds to 0374 * the `Literal | CatchallKey` that is the 0375 * element type of the `keys` array in the `Variant` interface 0376 * defined in https://github.com/unicode-org/message-format-wg/blob/main/spec/data-model.md#messages 0377 * 0378 * A key is either a literal or the wildcard symbol (represented in messages as '*') 0379 * 0380 * `Key` is immutable, copyable and movable. 0381 * 0382 * @internal ICU 75 technology preview 0383 * @deprecated This API is for technology preview only. 0384 */ 0385 class U_I18N_API Key : public UObject { 0386 public: 0387 /** 0388 * Determines if this is a wildcard key 0389 * 0390 * @return True if and only if this is the wildcard key 0391 * 0392 * @internal ICU 75 technology preview 0393 * @deprecated This API is for technology preview only. 0394 */ 0395 UBool isWildcard() const { return !contents.has_value(); } 0396 /** 0397 * Returns the contents of this key as a literal. 0398 * Precondition: !isWildcard() 0399 * 0400 * @return The literal contents of the key 0401 * 0402 * @internal ICU 75 technology preview 0403 * @deprecated This API is for technology preview only. 0404 */ 0405 const Literal& asLiteral() const; 0406 /** 0407 * Copy constructor. 0408 * 0409 * @internal ICU 75 technology preview 0410 * @deprecated This API is for technology preview only. 0411 */ 0412 Key(const Key& other) : contents(other.contents) {} 0413 /** 0414 * Wildcard constructor; constructs a Key representing the 0415 * catchall or wildcard key, '*'. 0416 * 0417 * @internal ICU 75 technology preview 0418 * @deprecated This API is for technology preview only. 0419 */ 0420 Key() : contents(std::nullopt) {} 0421 /** 0422 * Literal key constructor. 0423 * 0424 * @param lit A Literal to use for this key. The result matches the 0425 * literal `lit`. 0426 * 0427 * @internal ICU 75 technology preview 0428 * @deprecated This API is for technology preview only. 0429 */ 0430 explicit Key(const Literal& lit) : contents(lit) {} 0431 /** 0432 * Non-member swap function. 0433 * @param k1 will get k2's contents 0434 * @param k2 will get k1's contents 0435 * 0436 * @internal ICU 75 technology preview 0437 * @deprecated This API is for technology preview only. 0438 */ 0439 friend inline void swap(Key& k1, Key& k2) noexcept { 0440 using std::swap; 0441 0442 swap(k1.contents, k2.contents); 0443 } 0444 /** 0445 * Assignment operator 0446 * 0447 * @internal ICU 75 technology preview 0448 * @deprecated This API is for technology preview only. 0449 */ 0450 Key& operator=(Key) noexcept; 0451 /** 0452 * Less than operator. Compares the literal of `this` with the literal of `other`. 0453 * This method is used in representing the mapping from key lists to patterns 0454 * in a message with variants, and is not expected to be useful otherwise. 0455 * 0456 * @param other The Key to compare to this one. 0457 * @return true if the two `Key`s are not wildcards and if `this.asLiteral()` 0458 * < `other.asLiteral()`. 0459 * Returns false otherwise. 0460 * 0461 * @internal ICU 75 technology preview 0462 * @deprecated This API is for technology preview only. 0463 */ 0464 bool operator<(const Key& other) const; 0465 /** 0466 * Equality operator. Compares the literal of `this` with the literal of `other`. 0467 * This method is used in representing the mapping from key lists to patterns 0468 * in a message with variants, and is not expected to be useful otherwise. 0469 * 0470 * @param other The Key to compare to this one. 0471 * @return true if either both `Key`s are wildcards, or `this.asLiteral()` 0472 * == `other.asLiteral()`. 0473 * Returns false otherwise. 0474 * 0475 * @internal ICU 75 technology preview 0476 * @deprecated This API is for technology preview only. 0477 */ 0478 bool operator==(const Key& other) const; 0479 /** 0480 * Destructor. 0481 * 0482 * @internal ICU 75 technology preview 0483 * @deprecated This API is for technology preview only. 0484 */ 0485 virtual ~Key(); 0486 private: 0487 /* const */ std::optional<Literal> contents; 0488 }; // class Key 0489 } // namespace data_model 0490 } // namespace message2 0491 0492 /// @cond DOXYGEN_IGNORE 0493 // Export an explicit template instantiation of the LocalPointer that is used as a 0494 // data member of various MFDataModel classes. 0495 // (When building DLLs for Windows this is required.) 0496 // (See measunit_impl.h, datefmt.h, collationiterator.h, erarules.h and others 0497 // for similar examples.) 0498 #if U_PF_WINDOWS <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN 0499 template class U_I18N_API LocalPointerBase<message2::data_model::Key>; 0500 template class U_I18N_API LocalArray<message2::data_model::Key>; 0501 #endif 0502 /// @endcond 0503 0504 namespace message2 { 0505 namespace data_model { 0506 /** 0507 * The `SelectorKeys` class represents the key list for a single variant. 0508 * It corresponds to the `keys` array in the `Variant` interface 0509 * defined in https://github.com/unicode-org/message-format-wg/blob/main/spec/data-model.md#messages 0510 * 0511 * `SelectorKeys` is immutable, copyable and movable. 0512 * 0513 * @internal ICU 75 technology preview 0514 * @deprecated This API is for technology preview only. 0515 */ 0516 class U_I18N_API SelectorKeys : public UObject { 0517 public: 0518 /** 0519 * Returns the underlying list of keys. 0520 * 0521 * @return The list of keys for this variant. 0522 * Returns an empty list if allocating this `SelectorKeys` 0523 * object previously failed. 0524 * 0525 * @internal ICU 75 technology preview 0526 * @deprecated This API is for technology preview only. 0527 */ 0528 std::vector<Key> getKeys() const { 0529 return toStdVector<Key>(keys.getAlias(), len); 0530 } 0531 /** 0532 * The mutable `SelectorKeys::Builder` class allows the key list to be constructed 0533 * one key at a time. 0534 * 0535 * Builder is not copyable or movable. 0536 * 0537 * @internal ICU 75 technology preview 0538 * @deprecated This API is for technology preview only. 0539 */ 0540 class U_I18N_API Builder : public UMemory { 0541 private: 0542 friend class SelectorKeys; 0543 UVector* keys; // This is a raw pointer and not a LocalPointer<UVector> to avoid undefined behavior warnings, 0544 // since UVector is forward-declared 0545 // The vector owns its elements 0546 public: 0547 /** 0548 * Adds a single key to the list. 0549 * 0550 * @param key The key to be added. Passed by move 0551 * @param status Input/output error code 0552 * @return A reference to the builder. 0553 * 0554 * @internal ICU 75 technology preview 0555 * @deprecated This API is for technology preview only. 0556 */ 0557 Builder& add(Key&& key, UErrorCode& status) noexcept; 0558 /** 0559 * Constructs a new immutable `SelectorKeys` using the list of keys 0560 * set with previous `add()` calls. 0561 * 0562 * The builder object (`this`) can still be used after calling `build()`. 0563 * 0564 * @param status Input/output error code 0565 * @return The new SelectorKeys object 0566 * 0567 * @internal ICU 75 technology preview 0568 * @deprecated This API is for technology preview only. 0569 */ 0570 SelectorKeys build(UErrorCode& status) const; 0571 /** 0572 * Default constructor. 0573 * Returns a Builder with an empty list of keys. 0574 * 0575 * @param status Input/output error code 0576 * 0577 * @internal ICU 75 technology preview 0578 * @deprecated This API is for technology preview only. 0579 */ 0580 Builder(UErrorCode& status); 0581 /** 0582 * Destructor. 0583 * 0584 * @internal ICU 75 technology preview 0585 * @deprecated This API is for technology preview only. 0586 */ 0587 virtual ~Builder(); 0588 Builder(const Builder&) = delete; 0589 Builder& operator=(const Builder&) = delete; 0590 Builder(Builder&&) = delete; 0591 Builder& operator=(Builder&&) = delete; 0592 }; // class SelectorKeys::Builder 0593 /** 0594 * Less than operator. Compares the two key lists lexicographically. 0595 * This method makes it possible for a `SelectorKeys` to be used as a map 0596 * key, which allows variants to be represented as a map. It is not expected 0597 * to be useful otherwise. 0598 * 0599 * @param other The SelectorKeys to compare to this one. 0600 * @return true if `this` is less than `other`, comparing the two key lists 0601 * lexicographically. 0602 * Returns false otherwise. 0603 * 0604 * @internal ICU 75 technology preview 0605 * @deprecated This API is for technology preview only. 0606 */ 0607 bool operator<(const SelectorKeys& other) const; 0608 /** 0609 * Default constructor. 0610 * Puts the SelectorKeys into a valid but undefined state. 0611 * 0612 * @internal ICU 75 technology preview 0613 * @deprecated This API is for technology preview only. 0614 */ 0615 SelectorKeys() : len(0) {} 0616 /** 0617 * Non-member swap function. 0618 * @param s1 will get s2's contents 0619 * @param s2 will get s1's contents 0620 * 0621 * @internal ICU 75 technology preview 0622 * @deprecated This API is for technology preview only. 0623 */ 0624 friend inline void swap(SelectorKeys& s1, SelectorKeys& s2) noexcept { 0625 using std::swap; 0626 0627 swap(s1.len, s2.len); 0628 swap(s1.keys, s2.keys); 0629 } 0630 /** 0631 * Copy constructor. 0632 * 0633 * @internal ICU 75 technology preview 0634 * @deprecated This API is for technology preview only. 0635 */ 0636 SelectorKeys(const SelectorKeys& other); 0637 /** 0638 * Assignment operator. 0639 * 0640 * @internal ICU 75 technology preview 0641 * @deprecated This API is for technology preview only. 0642 */ 0643 SelectorKeys& operator=(SelectorKeys other) noexcept; 0644 /** 0645 * Destructor. 0646 * 0647 * @internal ICU 75 technology preview 0648 * @deprecated This API is for technology preview only. 0649 */ 0650 virtual ~SelectorKeys(); 0651 private: 0652 friend class Builder; 0653 friend class message2::Checker; 0654 friend class message2::MessageFormatter; 0655 friend class message2::Serializer; 0656 0657 /* const */ LocalArray<Key> keys; 0658 /* const */ int32_t len; 0659 0660 const Key* getKeysInternal() const; 0661 SelectorKeys(const UVector& ks, UErrorCode& status); 0662 }; // class SelectorKeys 0663 0664 0665 } // namespace data_model 0666 0667 0668 namespace data_model { 0669 class Operator; 0670 0671 /** 0672 * An `Option` pairs an option name with an Operand. 0673 * 0674 * `Option` is immutable, copyable and movable. 0675 * 0676 * @internal ICU 75 technology preview 0677 * @deprecated This API is for technology preview only. 0678 */ 0679 class U_I18N_API Option : public UObject { 0680 public: 0681 /** 0682 * Accesses the right-hand side of the option. 0683 * 0684 * @return A reference to the operand. 0685 * 0686 * @internal ICU 75 technology preview 0687 * @deprecated This API is for technology preview only. 0688 */ 0689 const Operand& getValue() const { return rand; } 0690 /** 0691 * Accesses the left-hand side of the option. 0692 * 0693 * @return A reference to the option name. 0694 * 0695 * @internal ICU 75 technology preview 0696 * @deprecated This API is for technology preview only. 0697 */ 0698 const UnicodeString& getName() const { return name; } 0699 /** 0700 * Constructor. Returns an `Option` representing the 0701 * named option "name=rand". 0702 * 0703 * @param n The name of the option. 0704 * @param r The value of the option. 0705 * 0706 * @internal ICU 75 technology preview 0707 * @deprecated This API is for technology preview only. 0708 */ 0709 Option(const UnicodeString& n, Operand&& r) : name(n), rand(std::move(r)) {} 0710 /** 0711 * Default constructor. 0712 * Returns an Option in a valid but undefined state. 0713 * 0714 * @internal ICU 75 technology preview 0715 * @deprecated This API is for technology preview only. 0716 */ 0717 Option() {} 0718 /** 0719 * Non-member swap function. 0720 * @param o1 will get o2's contents 0721 * @param o2 will get o1's contents 0722 * 0723 * @internal ICU 75 technology preview 0724 * @deprecated This API is for technology preview only. 0725 */ 0726 friend inline void swap(Option& o1, Option& o2) noexcept { 0727 using std::swap; 0728 0729 swap(o1.name, o2.name); 0730 swap(o1.rand, o2.rand); 0731 } 0732 /** 0733 * Copy constructor. 0734 * 0735 * @internal ICU 75 technology preview 0736 * @deprecated This API is for technology preview only. 0737 */ 0738 Option(const Option& other); 0739 /** 0740 * Assignment operator 0741 * 0742 * @internal ICU 75 technology preview 0743 * @deprecated This API is for technology preview only. 0744 */ 0745 Option& operator=(Option other) noexcept; 0746 /** 0747 * Destructor. 0748 * 0749 * @internal ICU 75 technology preview 0750 * @deprecated This API is for technology preview only. 0751 */ 0752 virtual ~Option(); 0753 private: 0754 /* const */ UnicodeString name; 0755 /* const */ Operand rand; 0756 }; // class Option 0757 } // namespace data_model 0758 } // namespace message2 0759 0760 /// @cond DOXYGEN_IGNORE 0761 // Export an explicit template instantiation of the LocalPointer that is used as a 0762 // data member of various MFDataModel classes. 0763 // (When building DLLs for Windows this is required.) 0764 // (See measunit_impl.h, datefmt.h, collationiterator.h, erarules.h and others 0765 // for similar examples.) 0766 #if U_PF_WINDOWS <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN 0767 template class U_I18N_API LocalPointerBase<message2::data_model::Option>; 0768 template class U_I18N_API LocalArray<message2::data_model::Option>; 0769 #endif 0770 /// @endcond 0771 0772 namespace message2 { 0773 namespace data_model { 0774 // Internal only 0775 #ifndef U_IN_DOXYGEN 0776 // Options 0777 // This is a wrapper class around a vector of options that provides lookup operations 0778 class U_I18N_API OptionMap : public UObject { 0779 public: 0780 int32_t size() const; 0781 // Needs to take an error code b/c an earlier copy might have failed 0782 const Option& getOption(int32_t, UErrorCode&) const; 0783 friend inline void swap(OptionMap& m1, OptionMap& m2) noexcept { 0784 using std::swap; 0785 0786 swap(m1.bogus, m2.bogus); 0787 swap(m1.options, m2.options); 0788 swap(m1.len, m2.len); 0789 } 0790 OptionMap() : len(0) {} 0791 OptionMap(const OptionMap&); 0792 OptionMap& operator=(OptionMap); 0793 std::vector<Option> getOptions() const { 0794 return toStdVector<Option>(options.getAlias(), len); 0795 } 0796 OptionMap(const UVector&, UErrorCode&); 0797 OptionMap(Option*, int32_t); 0798 virtual ~OptionMap(); 0799 0800 class U_I18N_API Builder : public UObject { 0801 private: 0802 UVector* options; 0803 bool checkDuplicates = true; 0804 public: 0805 Builder& add(Option&& opt, UErrorCode&); 0806 Builder(UErrorCode&); 0807 static Builder attributes(UErrorCode&); 0808 // As this class is private, build() is destructive 0809 OptionMap build(UErrorCode&); 0810 friend inline void swap(Builder& m1, Builder& m2) noexcept { 0811 using std::swap; 0812 0813 swap(m1.options, m2.options); 0814 swap(m1.checkDuplicates, m2.checkDuplicates); 0815 } 0816 Builder(Builder&&); 0817 Builder(const Builder&) = delete; 0818 Builder& operator=(Builder) noexcept; 0819 virtual ~Builder(); 0820 }; // class OptionMap::Builder 0821 private: 0822 friend class message2::Serializer; 0823 0824 bool bogus = false; 0825 LocalArray<Option> options; 0826 int32_t len; 0827 }; // class OptionMap 0828 #endif 0829 0830 } // namespace data_model 0831 } // namespace message2 0832 0833 U_NAMESPACE_END 0834 0835 U_NAMESPACE_BEGIN 0836 0837 namespace message2 { 0838 namespace data_model { 0839 /** 0840 * The `Operator` class corresponds to the `FunctionRef` type in the 0841 * `Expression` interface defined in 0842 * https://github.com/unicode-org/message-format-wg/blob/main/spec/data-model.md#patterns 0843 * 0844 * It represents the annotation that an expression can have: a function name paired 0845 * with a map from option names to operands (possibly empty). 0846 * 0847 * `Operator` is immutable, copyable and movable. 0848 * 0849 * @internal ICU 75 technology preview 0850 * @deprecated This API is for technology preview only. 0851 */ 0852 class U_I18N_API Operator : public UObject { 0853 public: 0854 /** 0855 * Accesses the function name. 0856 * 0857 * @return The function name of this operator. 0858 * 0859 * @internal ICU 75 technology preview 0860 * @deprecated This API is for technology preview only. 0861 */ 0862 const FunctionName& getFunctionName() const; 0863 /** 0864 * Accesses function options. 0865 * 0866 * @return A vector of function options for this operator. 0867 * 0868 * @internal ICU 75 technology preview 0869 * @deprecated This API is for technology preview only. 0870 */ 0871 std::vector<Option> getOptions() const { 0872 return options.getOptions(); 0873 } 0874 /** 0875 * The mutable `Operator::Builder` class allows the operator to be constructed 0876 * incrementally. 0877 * 0878 * Builder is not copyable or movable. 0879 * 0880 * @internal ICU 75 technology preview 0881 * @deprecated This API is for technology preview only. 0882 */ 0883 class U_I18N_API Builder : public UMemory { 0884 private: 0885 friend class Operator; 0886 FunctionName functionName; 0887 OptionMap::Builder options; 0888 public: 0889 /** 0890 * Sets this operator to be a function annotation and sets its name 0891 * to `func`. 0892 * 0893 * @param func The function name. 0894 * @return A reference to the builder. 0895 * 0896 * @internal ICU 75 technology preview 0897 * @deprecated This API is for technology preview only. 0898 */ 0899 Builder& setFunctionName(FunctionName&& func); 0900 /** 0901 * Sets this operator to be a function annotation and adds a 0902 * single option. 0903 * 0904 * @param key The name of the option. 0905 * @param value The value (right-hand side) of the option. 0906 * @param status Input/output error code. 0907 * @return A reference to the builder. 0908 * 0909 * @internal ICU 75 technology preview 0910 * @deprecated This API is for technology preview only. 0911 */ 0912 Builder& addOption(const UnicodeString &key, Operand&& value, UErrorCode& status) noexcept; 0913 /** 0914 * Constructs a new immutable `Operator` using the 0915 * function name and options that were previously set. 0916 * 0917 * The builder object (`this`) can still be used after calling `build()`. 0918 * 0919 * The `build()` method is non-const for internal implementation reasons, 0920 * but is observably const. 0921 * 0922 * @param status Input/output error code. 0923 * @return The new Operator 0924 * 0925 * @internal ICU 75 technology preview 0926 * @deprecated This API is for technology preview only. 0927 */ 0928 Operator build(UErrorCode& status); 0929 /** 0930 * Default constructor. 0931 * Returns a Builder with no function name or options set. 0932 * 0933 * @param status Input/output error code. 0934 * 0935 * @internal ICU 75 technology preview 0936 * @deprecated This API is for technology preview only. 0937 */ 0938 Builder(UErrorCode& status); 0939 /** 0940 * Destructor. 0941 * 0942 * @internal ICU 75 technology preview 0943 * @deprecated This API is for technology preview only. 0944 */ 0945 virtual ~Builder(); 0946 Builder(const Builder&) = delete; 0947 Builder& operator=(const Builder&) = delete; 0948 Builder(Builder&&) = delete; 0949 Builder& operator=(Builder&&) = delete; 0950 }; // class Operator::Builder 0951 /** 0952 * Copy constructor. 0953 * 0954 * @internal ICU 75 technology preview 0955 * @deprecated This API is for technology preview only. 0956 */ 0957 Operator(const Operator& other) noexcept; 0958 /** 0959 * Non-member swap function. 0960 * @param o1 will get o2's contents 0961 * @param o2 will get o1's contents 0962 * 0963 * @internal ICU 75 technology preview 0964 * @deprecated This API is for technology preview only. 0965 */ 0966 friend inline void swap(Operator& o1, Operator& o2) noexcept { 0967 using std::swap; 0968 0969 swap(o1.name, o2.name); 0970 swap(o1.options, o2.options); 0971 } 0972 /** 0973 * Assignment operator. 0974 * 0975 * @internal ICU 75 technology preview 0976 * @deprecated This API is for technology preview only. 0977 */ 0978 Operator& operator=(Operator) noexcept; 0979 /** 0980 * Default constructor. 0981 * Puts the Operator into a valid but undefined state. 0982 * 0983 * @internal ICU 75 technology preview 0984 * @deprecated This API is for technology preview only. 0985 */ 0986 Operator() {} 0987 /** 0988 * Destructor. 0989 * 0990 * @internal ICU 75 technology preview 0991 * @deprecated This API is for technology preview only. 0992 */ 0993 virtual ~Operator(); 0994 private: 0995 friend class Binding; 0996 friend class Builder; 0997 friend class message2::Checker; 0998 friend class message2::MessageFormatter; 0999 friend class message2::Serializer; 1000 1001 // Function call constructor 1002 Operator(const FunctionName& f, const UVector& options, UErrorCode&); 1003 1004 const OptionMap& getOptionsInternal() const; 1005 Operator(const FunctionName&, const OptionMap&); 1006 1007 /* const */ FunctionName name; 1008 /* const */ OptionMap options; 1009 }; // class Operator 1010 } // namespace data_model 1011 } // namespace message2 1012 1013 U_NAMESPACE_END 1014 1015 /// @cond DOXYGEN_IGNORE 1016 // Export an explicit template instantiation of the std::optional that is used as a 1017 // data member of various MFDataModel classes. 1018 // (When building DLLs for Windows this is required.) 1019 // (See measunit_impl.h, datefmt.h, collationiterator.h, erarules.h and others 1020 // for similar examples.) 1021 #if U_PF_WINDOWS <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN 1022 template class U_I18N_API std::optional<icu::message2::data_model::Operator>; 1023 #endif 1024 /// @endcond 1025 1026 U_NAMESPACE_BEGIN 1027 1028 namespace message2 { 1029 namespace data_model { 1030 // Internal only 1031 typedef enum UMarkupType { 1032 UMARKUP_OPEN = 0, 1033 UMARKUP_CLOSE, 1034 UMARKUP_STANDALONE, 1035 UMARKUP_COUNT 1036 } UMarkupType; 1037 1038 /** 1039 * The `Markup` class corresponds to the `markup` nonterminal in the MessageFormat 2 1040 * grammar and the `markup` interface defined in 1041 * https://github.com/unicode-org/message-format-wg/blob/main/spec/data-model/message.json 1042 * 1043 * `Markup` is immutable, copyable and movable. 1044 * 1045 * @internal ICU 75 technology preview 1046 * @deprecated This API is for technology preview only. 1047 */ 1048 class U_I18N_API Markup : public UObject { 1049 public: 1050 /** 1051 * Checks if this markup is an opening tag. 1052 * 1053 * @return True if and only if this represents an opening tag. 1054 * 1055 * @internal ICU 75 technology preview 1056 * @deprecated This API is for technology preview only. 1057 */ 1058 UBool isOpen() const { return (type == UMARKUP_OPEN); } 1059 /** 1060 * Checks if this markup is an closing tag. 1061 * 1062 * @return True if and only if this represents an closing tag. 1063 * 1064 * @internal ICU 75 technology preview 1065 * @deprecated This API is for technology preview only. 1066 */ 1067 UBool isClose() const { return (type == UMARKUP_CLOSE); } 1068 /** 1069 * Checks if this markup is an standalone tag. 1070 * 1071 * @return True if and only if this represents a standalone tag. 1072 * 1073 * @internal ICU 75 technology preview 1074 * @deprecated This API is for technology preview only. 1075 */ 1076 UBool isStandalone() const { return (type == UMARKUP_STANDALONE); } 1077 /** 1078 * Gets the name of this markup 1079 * 1080 * @return A reference to the string identifying the markup 1081 * 1082 * @internal ICU 75 technology preview 1083 * @deprecated This API is for technology preview only. 1084 */ 1085 const UnicodeString& getName() const { return name; } 1086 /** 1087 * Gets the options of this markup 1088 * 1089 * @return A reference to the string identifying the markup 1090 * 1091 * @internal ICU 75 technology preview 1092 * @deprecated This API is for technology preview only. 1093 */ 1094 std::vector<Option> getOptions() const { return options.getOptions(); } 1095 /** 1096 * Gets the attributes of this markup 1097 * 1098 * @return A vector of attributes 1099 * 1100 * @internal ICU 75 technology preview 1101 * @deprecated This API is for technology preview only. 1102 */ 1103 std::vector<Option> getAttributes() const { return attributes.getOptions(); } 1104 /** 1105 * Default constructor. 1106 * Puts the Markup into a valid but undefined state. 1107 * 1108 * @internal ICU 75 technology preview 1109 * @deprecated This API is for technology preview only. 1110 */ 1111 Markup() {} 1112 /** 1113 * Destructor. 1114 * 1115 * @internal ICU 75 technology preview 1116 * @deprecated This API is for technology preview only. 1117 */ 1118 virtual ~Markup(); 1119 /** 1120 * The mutable `Markup::Builder` class allows the markup to be constructed 1121 * incrementally. 1122 * 1123 * Builder is not copyable or movable. 1124 * 1125 * @internal ICU 75 technology preview 1126 * @deprecated This API is for technology preview only. 1127 */ 1128 class U_I18N_API Builder : public UMemory { 1129 private: 1130 friend class Markup; 1131 1132 UnicodeString name; 1133 OptionMap::Builder options; 1134 OptionMap::Builder attributes; 1135 UMarkupType type = UMARKUP_COUNT; 1136 public: 1137 /** 1138 * Sets the name of this markup. 1139 * 1140 * @param n A string representing the name. 1141 * @return A reference to the builder. 1142 * 1143 * @internal ICU 75 technology preview 1144 * @deprecated This API is for technology preview only. 1145 */ 1146 Builder& setName(const UnicodeString& n) { name = n; return *this; } 1147 /** 1148 * Sets this to be an opening markup. 1149 * 1150 * @return A reference to the builder. 1151 * 1152 * @internal ICU 75 technology preview 1153 * @deprecated This API is for technology preview only. 1154 */ 1155 Builder& setOpen() { type = UMARKUP_OPEN; return *this; } 1156 /** 1157 * Sets this to be an closing markup. 1158 * 1159 * @return A reference to the builder. 1160 * 1161 * @internal ICU 75 technology preview 1162 * @deprecated This API is for technology preview only. 1163 */ 1164 Builder& setClose() { type = UMARKUP_CLOSE; return *this; } 1165 /** 1166 * Sets this to be a standalone markup. 1167 * 1168 * @return A reference to the builder. 1169 * 1170 * @internal ICU 75 technology preview 1171 * @deprecated This API is for technology preview only. 1172 */ 1173 Builder& setStandalone() { type = UMARKUP_STANDALONE; return *this; } 1174 /** 1175 * Adds a single option. 1176 * 1177 * @param key The name of the option. 1178 * @param value The value (right-hand side) of the option. 1179 * @param status Input/output error code. 1180 * @return A reference to the builder. 1181 * 1182 * @internal ICU 75 technology preview 1183 * @deprecated This API is for technology preview only. 1184 */ 1185 Builder& addOption(const UnicodeString &key, Operand&& value, UErrorCode& status); 1186 /** 1187 * Adds a single attribute. 1188 * 1189 * @param key The name of the attribute. 1190 * @param value The value (right-hand side) of the attribute. 1191 * @param status Input/output error code. 1192 * @return A reference to the builder. 1193 * 1194 * @internal ICU 75 technology preview 1195 * @deprecated This API is for technology preview only. 1196 */ 1197 Builder& addAttribute(const UnicodeString &key, Operand&& value, UErrorCode& status); 1198 /** 1199 * Constructs a new immutable `Markup` using the name and type 1200 * and (optionally) options and attributes that were previously set. 1201 * If `setName()` and at least one of `setOpen()`, `setClose()`, and `setStandalone()` 1202 * were not previously called, 1203 * then `status` is set to U_INVALID_STATE_ERROR. 1204 * 1205 * The builder object (`this`) can still be used after calling `build()`. 1206 * The `build()` method is non-const for internal implementation reasons, 1207 * but is observably const. 1208 * 1209 * @param status Input/output error code. 1210 * @return The new Markup. 1211 * 1212 * @internal ICU 75 technology preview 1213 * @deprecated This API is for technology preview only. 1214 */ 1215 Markup build(UErrorCode& status); 1216 /** 1217 * Default constructor. 1218 * Returns a Builder with no name, type, options, or attributes set. 1219 * 1220 * @param status Input/output error code. 1221 * 1222 * @internal ICU 75 technology preview 1223 * @deprecated This API is for technology preview only. 1224 */ 1225 Builder(UErrorCode& status); 1226 /** 1227 * Destructor. 1228 * 1229 * @internal ICU 75 technology preview 1230 * @deprecated This API is for technology preview only. 1231 */ 1232 virtual ~Builder(); 1233 Builder(const Builder&) = delete; 1234 Builder& operator=(const Builder&) = delete; 1235 Builder(Builder&&) = delete; 1236 Builder& operator=(Builder&&) = delete; 1237 }; // class Markup::Builder 1238 1239 private: 1240 friend class Builder; 1241 friend class message2::Serializer; 1242 1243 UMarkupType type; 1244 UnicodeString name; 1245 OptionMap options; 1246 OptionMap attributes; 1247 const OptionMap& getOptionsInternal() const { return options; } 1248 const OptionMap& getAttributesInternal() const { return attributes; } 1249 Markup(UMarkupType, UnicodeString, OptionMap&&, OptionMap&&); 1250 }; // class Markup 1251 1252 /** 1253 * The `Expression` class corresponds to the `expression` nonterminal in the MessageFormat 2 1254 * grammar and the `Expression` interface defined in 1255 * https://github.com/unicode-org/message-format-wg/blob/main/spec/data-model.md#patterns 1256 * 1257 * It represents either an operand with no annotation; an annotation with no operand; 1258 * or an operand annotated with an annotation. 1259 * 1260 * `Expression` is immutable, copyable and movable. 1261 * 1262 * @internal ICU 75 technology preview 1263 * @deprecated This API is for technology preview only. 1264 */ 1265 class U_I18N_API Expression : public UObject { 1266 public: 1267 /** 1268 * Checks if this expression is an annotation 1269 * with no operand. 1270 * 1271 * @return True if and only if the expression has 1272 * an annotation and has no operand. 1273 * 1274 * @internal ICU 75 technology preview 1275 * @deprecated This API is for technology preview only. 1276 */ 1277 UBool isStandaloneAnnotation() const; 1278 /** 1279 * Checks if this expression has a function 1280 * annotation (with or without an operand). 1281 * 1282 * @return True if and only if the expression has an annotation 1283 * that is a function. 1284 * 1285 * @internal ICU 75 technology preview 1286 * @deprecated This API is for technology preview only. 1287 */ 1288 UBool isFunctionCall() const; 1289 /** 1290 * Accesses the function 1291 * annotating this expression. 1292 * If !(isFunctionCall()), sets 1293 * `status` to U_INVALID_STATE_ERROR. 1294 * 1295 * @param status Input/output error code. 1296 * @return A non-owned pointer to the operator of this expression, 1297 * which does not outlive the expression. 1298 * 1299 * @internal ICU 75 technology preview 1300 * @deprecated This API is for technology preview only. 1301 */ 1302 const Operator* getOperator(UErrorCode& status) const; 1303 /** 1304 * Accesses the operand of this expression. 1305 * 1306 * @return A reference to the operand of this expression, 1307 * which may be the null operand. 1308 * 1309 * @internal ICU 75 technology preview 1310 * @deprecated This API is for technology preview only. 1311 */ 1312 const Operand& getOperand() const; 1313 /** 1314 * Gets the attributes of this expression 1315 * 1316 * @return A vector of attributes 1317 * 1318 * @internal ICU 75 technology preview 1319 * @deprecated This API is for technology preview only. 1320 */ 1321 std::vector<Option> getAttributes() const { return attributes.getOptions(); } 1322 /** 1323 * The mutable `Expression::Builder` class allows the operator to be constructed 1324 * incrementally. 1325 * 1326 * Builder is not copyable or movable. 1327 * 1328 * @internal ICU 75 technology preview 1329 * @deprecated This API is for technology preview only. 1330 */ 1331 class U_I18N_API Builder : public UMemory { 1332 private: 1333 friend class Expression; 1334 1335 bool hasOperand = false; 1336 bool hasOperator = false; 1337 Operand rand; 1338 Operator rator; 1339 OptionMap::Builder attributes; 1340 public: 1341 /** 1342 * Sets the operand of this expression. 1343 * 1344 * @param rAnd The operand to set. Passed by move. 1345 * @return A reference to the builder. 1346 * 1347 * @internal ICU 75 technology preview 1348 * @deprecated This API is for technology preview only. 1349 */ 1350 Builder& setOperand(Operand&& rAnd); 1351 /** 1352 * Sets the operator of this expression. 1353 * 1354 * @param rAtor The operator to set. Passed by move. 1355 * @return A reference to the builder. 1356 * 1357 * @internal ICU 75 technology preview 1358 * @deprecated This API is for technology preview only. 1359 */ 1360 Builder& setOperator(Operator&& rAtor); 1361 /** 1362 * Adds a single attribute. 1363 * 1364 * @param key The name of the attribute. 1365 * @param value The value (right-hand side) of the attribute. 1366 * @param status Input/output error code. 1367 * @return A reference to the builder. 1368 * 1369 * @internal ICU 75 technology preview 1370 * @deprecated This API is for technology preview only. 1371 */ 1372 Builder& addAttribute(const UnicodeString &key, Operand&& value, UErrorCode& status); 1373 /** 1374 * Constructs a new immutable `Expression` using the operand and operator that 1375 * were previously set. If neither `setOperand()` nor `setOperator()` was 1376 * previously called, or if `setOperand()` was called with the null operand 1377 * and `setOperator()` was never called, then `status` is set to 1378 * U_INVALID_STATE_ERROR. 1379 * 1380 * The builder object (`this`) can still be used after calling `build()`. 1381 * The `build()` method is non-const for internal implementation reasons, 1382 * but is observably const. 1383 1384 * @param status Input/output error code. 1385 * @return The new Expression. 1386 * 1387 * @internal ICU 75 technology preview 1388 * @deprecated This API is for technology preview only. 1389 */ 1390 Expression build(UErrorCode& status); 1391 /** 1392 * Default constructor. 1393 * Returns a Builder with no operator or operand set. 1394 * 1395 * @param status Input/output error code. 1396 * 1397 * @internal ICU 75 technology preview 1398 * @deprecated This API is for technology preview only. 1399 */ 1400 Builder(UErrorCode& status); 1401 /** 1402 * Destructor. 1403 * 1404 * @internal ICU 75 technology preview 1405 * @deprecated This API is for technology preview only. 1406 */ 1407 virtual ~Builder(); 1408 Builder(const Builder&) = delete; 1409 Builder& operator=(const Builder&) = delete; 1410 Builder(Builder&&) = delete; 1411 Builder& operator=(Builder&&) = delete; 1412 }; // class Expression::Builder 1413 /** 1414 * Non-member swap function. 1415 * @param e1 will get e2's contents 1416 * @param e2 will get e1's contents 1417 * 1418 * @internal ICU 75 technology preview 1419 * @deprecated This API is for technology preview only. 1420 */ 1421 friend inline void swap(Expression& e1, Expression& e2) noexcept { 1422 using std::swap; 1423 1424 swap(e1.rator, e2.rator); 1425 swap(e1.rand, e2.rand); 1426 swap(e1.attributes, e2.attributes); 1427 } 1428 /** 1429 * Copy constructor. 1430 * 1431 * @internal ICU 75 technology preview 1432 * @deprecated This API is for technology preview only. 1433 */ 1434 Expression(const Expression& other); 1435 /** 1436 * Assignment operator. 1437 * 1438 * @internal ICU 75 technology preview 1439 * @deprecated This API is for technology preview only. 1440 */ 1441 Expression& operator=(Expression) noexcept; 1442 /** 1443 * Default constructor. 1444 * Puts the Expression into a valid but undefined state. 1445 * 1446 * @internal ICU 75 technology preview 1447 * @deprecated This API is for technology preview only. 1448 */ 1449 Expression(); 1450 /** 1451 * Destructor. 1452 * 1453 * @internal ICU 75 technology preview 1454 * @deprecated This API is for technology preview only. 1455 */ 1456 virtual ~Expression(); 1457 private: 1458 friend class message2::Serializer; 1459 1460 /* 1461 Internally, an expression is represented as the application of an optional operator to an operand. 1462 The operand is always present; for function calls with no operand, it's represented 1463 as an operand for which `isNull()` is true. 1464 1465 Operator | Operand 1466 -------------------------------- 1467 { |42| :fun opt=value } => (FunctionName=fun, | Literal(quoted=true, contents="42") 1468 options={opt: value}) 1469 { abcd } => null | Literal(quoted=false, contents="abcd") 1470 { : fun opt=value } => (FunctionName=fun, 1471 options={opt: value}) | NullOperand() 1472 */ 1473 1474 Expression(const Operator &rAtor, const Operand &rAnd, const OptionMap& attrs) : rator(rAtor), rand(rAnd), attributes(attrs) {} 1475 Expression(const Operand &rAnd, const OptionMap& attrs) : rator(std::nullopt), rand(Operand(rAnd)), attributes(attrs) {} 1476 Expression(const Operator &rAtor, const OptionMap& attrs) : rator(rAtor), rand(), attributes(attrs) {} 1477 /* const */ std::optional<Operator> rator; 1478 /* const */ Operand rand; 1479 /* const */ OptionMap attributes; 1480 const OptionMap& getAttributesInternal() const { return attributes; } 1481 }; // class Expression 1482 } // namespace data_model 1483 } // namespace message2 1484 1485 /// @cond DOXYGEN_IGNORE 1486 // Export an explicit template instantiation of the LocalPointer that is used as a 1487 // data member of various MFDataModel classes. 1488 // (When building DLLs for Windows this is required.) 1489 // (See measunit_impl.h, datefmt.h, collationiterator.h, erarules.h and others 1490 // for similar examples.) 1491 #if U_PF_WINDOWS <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN 1492 template class U_I18N_API LocalPointerBase<message2::data_model::Expression>; 1493 template class U_I18N_API LocalArray<message2::data_model::Expression>; 1494 #endif 1495 /// @endcond 1496 1497 namespace message2 { 1498 namespace data_model { 1499 1500 class Pattern; 1501 1502 // Despite the comments, `PatternPart` is internal-only 1503 /** 1504 * A `PatternPart` is a single element (text or expression) in a `Pattern`. 1505 * It corresponds to the `body` field of the `Pattern` interface 1506 * defined in https://github.com/unicode-org/message-format-wg/blob/main/spec/data-model.md#patterns 1507 * 1508 * `PatternPart` is immutable, copyable and movable. 1509 * 1510 * @internal ICU 75 technology preview 1511 * @deprecated This API is for technology preview only. 1512 */ 1513 class PatternPart : public UObject { 1514 public: 1515 /** 1516 * Checks if the part is a text part. 1517 * 1518 * @return True if and only if this is a text part. 1519 * 1520 * @internal ICU 75 technology preview 1521 * @deprecated This API is for technology preview only. 1522 */ 1523 UBool isText() const { return std::holds_alternative<UnicodeString>(piece); } 1524 /** 1525 * Checks if the part is a markup part. 1526 * 1527 * @return True if and only if this is a markup part. 1528 * 1529 * @internal ICU 75 technology preview 1530 * @deprecated This API is for technology preview only. 1531 */ 1532 UBool isMarkup() const { return std::holds_alternative<Markup>(piece); } 1533 /** 1534 * Checks if the part is an expression part. 1535 * 1536 * @return True if and only if this is an expression part. 1537 * 1538 * @internal ICU 75 technology preview 1539 * @deprecated This API is for technology preview only. 1540 */ 1541 UBool isExpression() const { return std::holds_alternative<Expression>(piece); } 1542 /** 1543 * Accesses the expression of the part. 1544 * Precondition: isExpression() 1545 * 1546 * @return A reference to the part's underlying expression. 1547 * 1548 * @internal ICU 75 technology preview 1549 * @deprecated This API is for technology preview only. 1550 */ 1551 const Expression& contents() const; 1552 /** 1553 * Accesses the expression of the part. 1554 * Precondition: isMarkup() 1555 * 1556 * @return A reference to the part's underlying expression. 1557 * 1558 * @internal ICU 75 technology preview 1559 * @deprecated This API is for technology preview only. 1560 */ 1561 const Markup& asMarkup() const; 1562 /** 1563 * Accesses the text contents of the part. 1564 * Precondition: isText() 1565 * 1566 * @return A reference to a string representing the part's text.. 1567 * 1568 * @internal ICU 75 technology preview 1569 * @deprecated This API is for technology preview only. 1570 */ 1571 const UnicodeString& asText() const; 1572 /** 1573 * Non-member swap function. 1574 * @param p1 will get p2's contents 1575 * @param p2 will get p1's contents 1576 * 1577 * @internal ICU 75 technology preview 1578 * @deprecated This API is for technology preview only. 1579 */ 1580 friend inline void swap(PatternPart& p1, PatternPart& p2) noexcept { 1581 using std::swap; 1582 1583 swap(p1.piece, p2.piece); 1584 } 1585 /** 1586 * Copy constructor. 1587 * 1588 * @internal ICU 75 technology preview 1589 * @deprecated This API is for technology preview only. 1590 */ 1591 PatternPart(const PatternPart& other); 1592 /** 1593 * Assignment operator. 1594 * 1595 * @internal ICU 75 technology preview 1596 * @deprecated This API is for technology preview only. 1597 */ 1598 PatternPart& operator=(PatternPart) noexcept; 1599 /** 1600 * Destructor. 1601 * 1602 * @internal ICU 75 technology preview 1603 * @deprecated This API is for technology preview only. 1604 */ 1605 virtual ~PatternPart(); 1606 /** 1607 * Text part constructor. Returns a text pattern part 1608 * with text `t`. 1609 * 1610 * @param t A text string. 1611 * 1612 * @internal ICU 75 technology preview 1613 * @deprecated This API is for technology preview only. 1614 */ 1615 explicit PatternPart(const UnicodeString& t) : piece(t) {} 1616 /** 1617 * Expression part constructor. Returns an Expression pattern 1618 * part with expression `e`. 1619 * 1620 * @param e An Expression. 1621 * 1622 * @internal ICU 75 technology preview 1623 * @deprecated This API is for technology preview only. 1624 */ 1625 explicit PatternPart(Expression&& e) : piece(e) {} 1626 /** 1627 * Markup part constructor. Returns a Markup pattern 1628 * part with markup `m` 1629 * 1630 * @param m A Markup. 1631 * 1632 * @internal ICU 75 technology preview 1633 * @deprecated This API is for technology preview only. 1634 */ 1635 explicit PatternPart(Markup&& m) : piece(m) {} 1636 /** 1637 * Default constructor. 1638 * Puts the PatternPart into a valid but undefined state. 1639 * 1640 * @internal ICU 75 technology preview 1641 * @deprecated This API is for technology preview only. 1642 */ 1643 PatternPart() = default; 1644 private: 1645 friend class Pattern; 1646 1647 std::variant<UnicodeString, Expression, Markup> piece; 1648 }; // class PatternPart 1649 } // namespace data_model 1650 } // namespace message2 1651 1652 /// @cond DOXYGEN_IGNORE 1653 // Export an explicit template instantiation of the LocalPointer that is used as a 1654 // data member of various MFDataModel classes. 1655 // (When building DLLs for Windows this is required.) 1656 // (See measunit_impl.h, datefmt.h, collationiterator.h, erarules.h and others 1657 // for similar examples.) 1658 #if U_PF_WINDOWS <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN 1659 template class U_I18N_API LocalPointerBase<message2::data_model::PatternPart>; 1660 template class U_I18N_API LocalArray<message2::data_model::PatternPart>; 1661 #endif 1662 /// @endcond 1663 1664 namespace message2 { 1665 namespace data_model { 1666 /** 1667 * A `Pattern` is a sequence of formattable parts. 1668 * It corresponds to the `Pattern` interface 1669 * defined in https://github.com/unicode-org/message-format-wg/blob/main/spec/data-model.md#patterns 1670 * 1671 * `Pattern` is immutable, copyable and movable. 1672 * 1673 * @internal ICU 75 technology preview 1674 * @deprecated This API is for technology preview only. 1675 */ 1676 class U_I18N_API Pattern : public UObject { 1677 private: 1678 friend class PatternPart; 1679 1680 public: 1681 struct Iterator; 1682 /** 1683 * Returns the parts of this pattern 1684 * 1685 * @return A forward iterator of variants. Each element is either a string (text part) 1686 * or an expression part. 1687 * 1688 * @internal ICU 75 technology preview 1689 * @deprecated This API is for technology preview only. 1690 */ 1691 Iterator begin() const { 1692 return Iterator(this, 0); 1693 } 1694 /** 1695 * Returns a special value to mark the end of iteration 1696 * 1697 * @return A forward iterator of variants. This should only be used for comparisons 1698 * against an iterator returned by incrementing begin(). 1699 * 1700 * @internal ICU 75 technology preview 1701 * @deprecated This API is for technology preview only. 1702 */ 1703 Iterator end() const { 1704 return Iterator(this, len); 1705 } 1706 /** 1707 * The mutable `Pattern::Builder` class allows the pattern to be 1708 * constructed one part at a time. 1709 * 1710 * Builder is not copyable or movable. 1711 * 1712 * @internal ICU 75 technology preview 1713 * @deprecated This API is for technology preview only. 1714 */ 1715 class U_I18N_API Builder : public UMemory { 1716 private: 1717 friend class Pattern; 1718 1719 UVector* parts; // Not a LocalPointer for the same reason as in `SelectorKeys::Builder` 1720 1721 public: 1722 /** 1723 * Adds a single expression part to the pattern. 1724 * 1725 * @param part The part to be added (passed by move) 1726 * @param status Input/output error code. 1727 * @return A reference to the builder. 1728 * 1729 * @internal ICU 75 technology preview 1730 * @deprecated This API is for technology preview only. 1731 */ 1732 Builder& add(Expression&& part, UErrorCode& status) noexcept; 1733 /** 1734 * Adds a single markup part to the pattern. 1735 * 1736 * @param part The part to be added (passed by move) 1737 * @param status Input/output error code. 1738 * @return A reference to the builder. 1739 * 1740 * @internal ICU 75 technology preview 1741 * @deprecated This API is for technology preview only. 1742 */ 1743 Builder& add(Markup&& part, UErrorCode& status) noexcept; 1744 /** 1745 * Adds a single text part to the pattern. Copies `part`. 1746 * 1747 * @param part The part to be added (passed by move) 1748 * @param status Input/output error code. 1749 * @return A reference to the builder. 1750 * 1751 * @internal ICU 75 technology preview 1752 * @deprecated This API is for technology preview only. 1753 */ 1754 Builder& add(UnicodeString&& part, UErrorCode& status) noexcept; 1755 /** 1756 * Constructs a new immutable `Pattern` using the list of parts 1757 * set with previous `add()` calls. 1758 * 1759 * The builder object (`this`) can still be used after calling `build()`. 1760 * 1761 * @param status Input/output error code. 1762 * @return The pattern object 1763 * 1764 * @internal ICU 75 technology preview 1765 * @deprecated This API is for technology preview only. 1766 */ 1767 Pattern build(UErrorCode& status) const noexcept; 1768 /** 1769 * Default constructor. 1770 * Returns a Builder with an empty sequence of PatternParts. 1771 * 1772 * @param status Input/output error code 1773 * 1774 * @internal ICU 75 technology preview 1775 * @deprecated This API is for technology preview only. 1776 */ 1777 Builder(UErrorCode& status); 1778 /** 1779 * Destructor. 1780 * 1781 * @internal ICU 75 technology preview 1782 * @deprecated This API is for technology preview only. 1783 */ 1784 virtual ~Builder(); 1785 Builder(const Builder&) = delete; 1786 Builder& operator=(const Builder&) = delete; 1787 Builder(Builder&&) = delete; 1788 Builder& operator=(Builder&&) = delete; 1789 }; // class Pattern::Builder 1790 1791 /** 1792 * Default constructor. 1793 * Puts the Pattern into a valid but undefined state. 1794 * 1795 * @internal ICU 75 technology preview 1796 * @deprecated This API is for technology preview only. 1797 */ 1798 Pattern() : parts(LocalArray<PatternPart>()) {} 1799 /** 1800 * Non-member swap function. 1801 * @param p1 will get p2's contents 1802 * @param p2 will get p1's contents 1803 * 1804 * @internal ICU 75 technology preview 1805 * @deprecated This API is for technology preview only. 1806 */ 1807 friend inline void swap(Pattern& p1, Pattern& p2) noexcept { 1808 using std::swap; 1809 1810 swap(p1.bogus, p2.bogus); 1811 swap(p1.len, p2.len); 1812 swap(p1.parts, p2.parts); 1813 } 1814 /** 1815 * Copy constructor. 1816 * 1817 * @internal ICU 75 technology preview 1818 * @deprecated This API is for technology preview only. 1819 */ 1820 Pattern(const Pattern& other); 1821 /** 1822 * Assignment operator 1823 * 1824 * @internal ICU 75 technology preview 1825 * @deprecated This API is for technology preview only. 1826 */ 1827 Pattern& operator=(Pattern) noexcept; 1828 /** 1829 * Destructor. 1830 * 1831 * @internal ICU 75 technology preview 1832 * @deprecated This API is for technology preview only. 1833 */ 1834 virtual ~Pattern(); 1835 1836 /** 1837 * The `Pattern::Iterator` class provides an iterator over the formattable 1838 * parts of a pattern. 1839 * 1840 * `Pattern::Iterator` is mutable and is not copyable or movable. 1841 * 1842 * @internal ICU 75 technology preview 1843 * @deprecated This API is for technology preview only. 1844 */ 1845 struct U_I18N_API Iterator { 1846 private: 1847 using iterator_category = std::forward_iterator_tag; 1848 using difference_type = std::ptrdiff_t; 1849 using value_type = std::variant<UnicodeString, Expression, Markup>; 1850 using pointer = value_type*; 1851 using reference = const value_type&; 1852 1853 friend class Pattern; 1854 Iterator(const Pattern* p, int32_t i) : pos(i), pat(p) {} 1855 friend bool operator== (const Iterator& a, const Iterator& b) { return (a.pat == b.pat && a.pos == b.pos); } 1856 1857 int32_t pos; 1858 const Pattern* pat; 1859 1860 public: 1861 /** 1862 * Dereference operator (gets the element at the current iterator position) 1863 * 1864 * @internal ICU 75 technology preview 1865 * @deprecated This API is for technology preview only. 1866 */ 1867 reference operator*() const { 1868 const PatternPart& part = pat->parts[pos]; 1869 return patternContents(part); 1870 } 1871 /** 1872 * Increment operator (advances to the next iterator position) 1873 * 1874 * @internal ICU 75 technology preview 1875 * @deprecated This API is for technology preview only. 1876 */ 1877 Iterator operator++() { pos++; return *this; } 1878 /** 1879 * Inequality comparison operator (used for comparing an iterator to the result of end()) 1880 * 1881 * @internal ICU 75 technology preview 1882 * @deprecated This API is for technology preview only. 1883 */ 1884 friend bool operator!= (const Iterator& a, const Iterator& b) { return !(a == b); } 1885 }; // struct Iterator 1886 1887 private: 1888 friend class Builder; 1889 friend class message2::MessageFormatter; 1890 friend class message2::Serializer; 1891 1892 // Set to true if a copy constructor fails; 1893 // needed in order to distinguish an uninitialized 1894 // Pattern from a 0-length pattern 1895 bool bogus = false; 1896 1897 // Possibly-empty array of parts 1898 int32_t len = 0; 1899 LocalArray<PatternPart> parts; 1900 1901 Pattern(const UVector& parts, UErrorCode& status); 1902 // Helper 1903 static void initParts(Pattern&, const Pattern&); 1904 1905 /** 1906 * Returns the size. 1907 * 1908 * @return The number of parts in the pattern. 1909 * 1910 * @internal ICU 75 technology preview 1911 * @deprecated This API is for technology preview only. 1912 */ 1913 int32_t numParts() const; 1914 /** 1915 * Returns the `i`th part in the pattern. 1916 * Precondition: i < numParts() 1917 * 1918 * @param i Index of the part being accessed. 1919 * @return A reference to the part at index `i`. 1920 * 1921 * @internal ICU 75 technology preview 1922 * @deprecated This API is for technology preview only. 1923 */ 1924 const PatternPart& getPart(int32_t i) const; 1925 1926 // Gets around not being able to declare Pattern::Iterator as a friend 1927 // in PatternPart 1928 static const std::variant<UnicodeString, Expression, Markup>& 1929 patternContents(const PatternPart& p) { return p.piece; } 1930 }; // class Pattern 1931 1932 /** 1933 * A `Variant` pairs a list of keys with a pattern 1934 * It corresponds to the `Variant` interface 1935 * defined in https://github.com/unicode-org/message-format-wg/tree/main/spec/data-model 1936 * 1937 * `Variant` is immutable, copyable and movable. 1938 * 1939 * @internal ICU 75 technology preview 1940 * @deprecated This API is for technology preview only. 1941 */ 1942 class U_I18N_API Variant : public UObject { 1943 public: 1944 /** 1945 * Accesses the pattern of the variant. 1946 * 1947 * @return A reference to the pattern. 1948 * 1949 * @internal ICU 75 technology preview 1950 * @deprecated This API is for technology preview only. 1951 */ 1952 const Pattern& getPattern() const { return p; } 1953 /** 1954 * Accesses the keys of the variant. 1955 * 1956 * @return A reference to the keys. 1957 * 1958 * @internal ICU 75 technology preview 1959 * @deprecated This API is for technology preview only. 1960 */ 1961 const SelectorKeys& getKeys() const { return k; } 1962 /** 1963 * Constructor. Returns a variant that formats to `pattern` 1964 * when `keys` match the selector expressions in the enclosing 1965 * `match` construct. 1966 * 1967 * @param keys A reference to a `SelectorKeys`. 1968 * @param pattern A pattern (passed by move) 1969 * 1970 * @internal ICU 75 technology preview 1971 * @deprecated This API is for technology preview only. 1972 */ 1973 Variant(const SelectorKeys& keys, Pattern&& pattern) : k(keys), p(std::move(pattern)) {} 1974 /** 1975 * Non-member swap function. 1976 * @param v1 will get v2's contents 1977 * @param v2 will get v1's contents 1978 * 1979 * @internal ICU 75 technology preview 1980 * @deprecated This API is for technology preview only. 1981 */ 1982 friend inline void swap(Variant& v1, Variant& v2) noexcept { 1983 using std::swap; 1984 1985 swap(v1.k, v2.k); 1986 swap(v1.p, v2.p); 1987 } 1988 /** 1989 * Assignment operator 1990 * 1991 * @internal ICU 75 technology preview 1992 * @deprecated This API is for technology preview only. 1993 */ 1994 Variant& operator=(Variant other) noexcept; 1995 /** 1996 * Default constructor. 1997 * Returns a Variant in a valid but undefined state. 1998 * 1999 * @internal ICU 75 technology preview 2000 * @deprecated This API is for technology preview only. 2001 */ 2002 Variant() = default; 2003 /** 2004 * Copy constructor. 2005 * 2006 * @internal ICU 75 technology preview 2007 * @deprecated This API is for technology preview only. 2008 */ 2009 Variant(const Variant&); 2010 /** 2011 * Destructor. 2012 * 2013 * @internal ICU 75 technology preview 2014 * @deprecated This API is for technology preview only. 2015 */ 2016 virtual ~Variant(); 2017 private: 2018 /* const */ SelectorKeys k; 2019 /* const */ Pattern p; 2020 }; // class Variant 2021 } // namespace data_model 2022 2023 namespace data_model { 2024 /** 2025 * A `Binding` pairs a variable name with an expression. 2026 * It corresponds to the `Declaration` interface 2027 * defined in https://github.com/unicode-org/message-format-wg/blob/main/spec/data-model.md#messages 2028 * 2029 * `Binding` is immutable and copyable. It is not movable. 2030 * 2031 * @internal ICU 75 technology preview 2032 * @deprecated This API is for technology preview only. 2033 */ 2034 class U_I18N_API Binding : public UObject { 2035 public: 2036 /** 2037 * Accesses the right-hand side of a binding. 2038 * 2039 * @return A reference to the expression. 2040 * 2041 * @internal ICU 75 technology preview 2042 * @deprecated This API is for technology preview only. 2043 */ 2044 const Expression& getValue() const; 2045 /** 2046 * Accesses the left-hand side of the binding. 2047 * 2048 * @return A reference to the variable name. 2049 * 2050 * @internal ICU 75 technology preview 2051 * @deprecated This API is for technology preview only. 2052 */ 2053 const VariableName& getVariable() const { return var; } 2054 /** 2055 * Constructor for input binding. 2056 * 2057 * @param variableName The variable name (left-hand side) of the binding. Passed by move. 2058 * @param rhs The right-hand side of the input binding. Passed by move. 2059 * `rhs` must have an operand that is a variable reference to `variableName`. 2060 * If `rhs` has an operator, it must be a function call. 2061 * If either of these properties is violated, `errorCode` is set to 2062 * U_INVALID_STATE_ERROR. 2063 * @param errorCode Input/output error code 2064 * 2065 * @internal ICU 75 technology preview 2066 * @deprecated This API is for technology preview only. 2067 */ 2068 static Binding input(UnicodeString&& variableName, Expression&& rhs, UErrorCode& errorCode); 2069 /** 2070 * Returns true if and only if this binding represents a local declaration. 2071 * Otherwise, it's an input declaration. 2072 * 2073 * @return True if this binding represents a variable and expression; 2074 * false if it represents a variable plus an annotation. 2075 */ 2076 UBool isLocal() const { return local; } 2077 /** 2078 * Constructor. 2079 * 2080 * @param v A variable name. 2081 * @param e An expression. 2082 * 2083 * @internal ICU 75 technology preview 2084 * @deprecated This API is for technology preview only. 2085 */ 2086 Binding(const VariableName& v, Expression&& e) : var(v), expr(std::move(e)), local(true), annotation(nullptr) {} 2087 /** 2088 * Non-member swap function. 2089 * @param b1 will get b2's contents 2090 * @param b2 will get b1's contents 2091 * 2092 * @internal ICU 75 technology preview 2093 * @deprecated This API is for technology preview only. 2094 */ 2095 friend inline void swap(Binding& b1, Binding& b2) noexcept { 2096 using std::swap; 2097 2098 swap(b1.var, b2.var); 2099 swap(b1.expr, b2.expr); 2100 swap(b1.local, b2.local); 2101 b1.updateAnnotation(); 2102 b2.updateAnnotation(); 2103 } 2104 /** 2105 * Copy constructor. 2106 * 2107 * @internal ICU 75 technology preview 2108 * @deprecated This API is for technology preview only. 2109 */ 2110 Binding(const Binding& other); 2111 /** 2112 * Copy assignment operator 2113 * 2114 * @internal ICU 75 technology preview 2115 * @deprecated This API is for technology preview only. 2116 */ 2117 Binding& operator=(Binding) noexcept; 2118 /** 2119 * Default constructor. 2120 * Puts the Binding into a valid but undefined state. 2121 * 2122 * @internal ICU 75 technology preview 2123 * @deprecated This API is for technology preview only. 2124 */ 2125 Binding() : local(true) {} 2126 /** 2127 * Destructor. 2128 * 2129 * @internal ICU 75 technology preview 2130 * @deprecated This API is for technology preview only. 2131 */ 2132 virtual ~Binding(); 2133 private: 2134 friend class message2::Checker; 2135 friend class message2::MessageFormatter; 2136 friend class message2::Parser; 2137 friend class message2::Serializer; 2138 2139 /* const */ VariableName var; 2140 /* const */ Expression expr; 2141 /* const */ bool local; 2142 2143 // The following field is always nullptr for a local 2144 // declaration, and possibly nullptr for an .input declaration 2145 // If non-null, the referent is a member of `expr` so 2146 // its lifetime is the same as the lifetime of the enclosing Binding 2147 // (as long as there's no mutation) 2148 const Operator* annotation = nullptr; 2149 2150 const OptionMap& getOptionsInternal() const; 2151 2152 bool hasAnnotation() const { return !local && (annotation != nullptr); } 2153 void updateAnnotation(); 2154 }; // class Binding 2155 } // namespace data_model 2156 } // namespace message2 2157 2158 /// @cond DOXYGEN_IGNORE 2159 // Export an explicit template instantiation of the LocalPointer that is used as a 2160 // data member of various MFDataModel classes. 2161 // (When building DLLs for Windows this is required.) 2162 // (See measunit_impl.h, datefmt.h, collationiterator.h, erarules.h and others 2163 // for similar examples.) 2164 #if U_PF_WINDOWS <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN 2165 template class U_I18N_API LocalPointerBase<message2::data_model::Variant>; 2166 template class U_I18N_API LocalPointerBase<message2::data_model::Binding>; 2167 template class U_I18N_API LocalArray<message2::data_model::Variant>; 2168 template class U_I18N_API LocalArray<message2::data_model::Binding>; 2169 #endif 2170 /// @endcond 2171 2172 namespace message2 { 2173 using namespace data_model; 2174 2175 2176 // Internal only 2177 2178 class MFDataModel; 2179 2180 #ifndef U_IN_DOXYGEN 2181 class Matcher : public UObject { 2182 public: 2183 Matcher& operator=(Matcher); 2184 Matcher(const Matcher&); 2185 /** 2186 * Non-member swap function. 2187 * @param m1 will get m2's contents 2188 * @param m2 will get m1's contents 2189 * 2190 * @internal ICU 75 technology preview 2191 * @deprecated This API is for technology preview only. 2192 */ 2193 friend inline void swap(Matcher& m1, Matcher& m2) noexcept { 2194 using std::swap; 2195 2196 if (m1.bogus) { 2197 m2.bogus = true; 2198 return; 2199 } 2200 if (m2.bogus) { 2201 m1.bogus = true; 2202 return; 2203 } 2204 swap(m1.selectors, m2.selectors); 2205 swap(m1.numSelectors, m2.numSelectors); 2206 swap(m1.variants, m2.variants); 2207 swap(m1.numVariants, m2.numVariants); 2208 } 2209 virtual ~Matcher(); 2210 private: 2211 2212 friend class MFDataModel; 2213 2214 Matcher(Expression* ss, int32_t ns, Variant* vs, int32_t nv); 2215 Matcher() {} 2216 2217 // A Matcher may have numSelectors=0 and numVariants=0 2218 // (this is a data model error, but it's representable). 2219 // So we have to keep a separate flag to track failed copies. 2220 bool bogus = false; 2221 2222 // The expressions that are being matched on. 2223 LocalArray<Expression> selectors; 2224 // The number of selectors 2225 int32_t numSelectors = 0; 2226 // The list of `when` clauses (case arms). 2227 LocalArray<Variant> variants; 2228 // The number of variants 2229 int32_t numVariants = 0; 2230 }; // class Matcher 2231 #endif 2232 } // namespace message2 2233 2234 U_NAMESPACE_END 2235 2236 /// @cond DOXYGEN_IGNORE 2237 // Export an explicit template instantiation of the std::variant that is used as a 2238 // data member of various MFDataModel classes. 2239 // (When building DLLs for Windows this is required.) 2240 // (See measunit_impl.h, datefmt.h, collationiterator.h, erarules.h and others 2241 // for similar examples.) 2242 #if U_PF_WINDOWS <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN 2243 #if defined(U_REAL_MSVC) && defined(_MSVC_STL_VERSION) 2244 template class U_I18N_API std::_Variant_storage_<false, icu::message2::Matcher,icu::message2::data_model::Pattern>; 2245 #endif 2246 template class U_I18N_API std::variant<icu::message2::Matcher,icu::message2::data_model::Pattern>; 2247 #endif 2248 /// @endcond 2249 2250 U_NAMESPACE_BEGIN 2251 2252 namespace message2 { 2253 // ----------------------------------------------------------------------- 2254 // Public MFDataModel class 2255 2256 /** 2257 * 2258 * The `MFDataModel` class describes a parsed representation of the text of a message. 2259 * This representation is public as higher-level APIs for messages will need to know its public 2260 * interface: for example, to re-instantiate a parsed message with different values for imported 2261 variables. 2262 * 2263 * The MFDataModel API implements <a target="github" 2264 href="https://github.com/unicode-org/message-format-wg/blob/main/spec/data-model.md">the 2265 * specification of the abstract syntax (data model representation)</a> for MessageFormat. 2266 * 2267 * `MFDataModel` is immutable, copyable and movable. 2268 * 2269 * @internal ICU 75 technology preview 2270 * @deprecated This API is for technology preview only. 2271 */ 2272 class U_I18N_API MFDataModel : public UMemory { 2273 /* 2274 Classes that represent nodes in the data model are nested inside the 2275 `MFDataModel` class. 2276 2277 Classes such as `Expression`, `Pattern` and `VariantMap` are immutable and 2278 are constructed using the builder pattern. 2279 2280 Most classes representing nodes have copy constructors. This is because builders 2281 contain immutable data that must be copied when calling `build()`, since the builder 2282 could go out of scope before the immutable result of the builder does. Copying is 2283 also necessary to prevent unexpected mutation if intermediate builders are saved 2284 and mutated again after calling `build()`. 2285 2286 The copy constructors perform a deep copy, for example by copying the entire 2287 list of options for an `Operator` (and copying the entire underlying vector.) 2288 Some internal fields should be `const`, but are declared as non-`const` to make 2289 the copy constructor simpler to implement. (These are noted throughout.) In 2290 other words, those fields are `const` except during the execution of a copy 2291 constructor. 2292 2293 On the other hand, intermediate `Builder` methods that return a `Builder&` 2294 mutate the state of the builder, so in code like: 2295 2296 Expression::Builder& exprBuilder = Expression::builder()-> setOperand(foo); 2297 Expression::Builder& exprBuilder2 = exprBuilder.setOperator(bar); 2298 2299 the call to `setOperator()` would mutate `exprBuilder`, since `exprBuilder` 2300 and `exprBuilder2` are references to the same object. 2301 2302 An alternate choice would be to make `build()` destructive, so that copying would 2303 be unnecessary. Or, both copying and moving variants of `build()` could be 2304 provided. Copying variants of the intermediate `Builder` methods could be 2305 provided as well, if this proved useful. 2306 */ 2307 public: 2308 /** 2309 * Accesses the local variable declarations for this data model. 2310 * 2311 * @return A vector of bindings for local variables. 2312 * 2313 * @internal ICU 75 technology preview 2314 * @deprecated This API is for technology preview only. 2315 */ 2316 std::vector<Binding> getLocalVariables() const { 2317 std::vector<Binding> result; 2318 if (!bogus) { 2319 return toStdVector<Binding>(bindings.getAlias(), bindingsLen); 2320 } 2321 return {}; 2322 } 2323 /** 2324 * Accesses the selectors. Returns an empty vector if this is a pattern message. 2325 * 2326 * @return A vector of selectors. 2327 * 2328 * @internal ICU 75 technology preview 2329 * @deprecated This API is for technology preview only. 2330 */ 2331 const std::vector<Expression> getSelectors() const { 2332 if (std::holds_alternative<Pattern>(body)) { 2333 return {}; 2334 } 2335 const Matcher* match = std::get_if<Matcher>(&body); 2336 // match must be non-null, given the previous check 2337 return toStdVector<Expression>(match->selectors.getAlias(), match->numSelectors); 2338 } 2339 /** 2340 * Accesses the variants. Returns an empty vector if this is a pattern message. 2341 * 2342 * @return A vector of variants. 2343 * 2344 * @internal ICU 75 technology preview 2345 * @deprecated This API is for technology preview only. 2346 */ 2347 std::vector<Variant> getVariants() const { 2348 // Return empty vector if no variants 2349 if (std::holds_alternative<Pattern>(body)) { 2350 return {}; 2351 } 2352 const Matcher* match = std::get_if<Matcher>(&body); 2353 // match must be non-null, given the previous check 2354 return toStdVector<Variant>(match->variants.getAlias(), match->numVariants); 2355 return {}; 2356 } 2357 /** 2358 * Accesses the pattern (in a message without selectors). 2359 * Returns a reference to an empty pattern if the message has selectors. 2360 * 2361 * @return A reference to the pattern. 2362 * 2363 * @internal ICU 75 technology preview 2364 * @deprecated This API is for technology preview only. 2365 */ 2366 const Pattern& getPattern() const; 2367 2368 /** 2369 * The mutable `MFDataModel::Builder` class allows the data model to be 2370 * constructed incrementally. 2371 * 2372 * @internal ICU 75 technology preview 2373 * @deprecated This API is for technology preview only. 2374 */ 2375 class U_I18N_API Builder; 2376 2377 /** 2378 * Default constructor. 2379 * Puts the MFDataModel into a valid but undefined state. 2380 * 2381 * @internal ICU 75 technology preview 2382 * @deprecated This API is for technology preview only. 2383 */ 2384 MFDataModel(); 2385 /** 2386 * Non-member swap function. 2387 * @param m1 will get m2's contents 2388 * @param m2 will get m1's contents 2389 * 2390 * @internal ICU 75 technology preview 2391 * @deprecated This API is for technology preview only. 2392 */ 2393 friend inline void swap(MFDataModel& m1, MFDataModel& m2) noexcept { 2394 using std::swap; 2395 2396 if (m1.bogus) { 2397 m2.bogus = true; 2398 return; 2399 } 2400 if (m2.bogus) { 2401 m1.bogus = true; 2402 return; 2403 } 2404 swap(m1.body, m2.body); 2405 swap(m1.bindings, m2.bindings); 2406 swap(m1.bindingsLen, m2.bindingsLen); 2407 } 2408 /** 2409 * Assignment operator 2410 * 2411 * @internal ICU 75 technology preview 2412 * @deprecated This API is for technology preview only. 2413 */ 2414 MFDataModel& operator=(MFDataModel) noexcept; 2415 /** 2416 * Copy constructor. 2417 * 2418 * @internal ICU 75 technology preview 2419 * @deprecated This API is for technology preview only. 2420 */ 2421 MFDataModel(const MFDataModel& other); 2422 /** 2423 * Destructor. 2424 * 2425 * @internal ICU 75 technology preview 2426 * @deprecated This API is for technology preview only. 2427 */ 2428 virtual ~MFDataModel(); 2429 2430 /** 2431 * The mutable `MFDataModel::Builder` class allows the data model to be 2432 * constructed incrementally. Builder is not copyable or movable. 2433 * 2434 * @internal ICU 75 technology preview 2435 * @deprecated This API is for technology preview only. 2436 */ 2437 class U_I18N_API Builder : public UMemory { 2438 private: 2439 friend class MFDataModel; 2440 2441 void checkDuplicate(const VariableName&, UErrorCode&) const; 2442 void buildSelectorsMessage(UErrorCode&); 2443 bool hasPattern = true; 2444 bool hasSelectors = false; 2445 Pattern pattern; 2446 // The following members are not LocalPointers for the same reason as in SelectorKeys::Builder 2447 UVector* selectors = nullptr; 2448 UVector* variants = nullptr; 2449 UVector* bindings = nullptr; 2450 public: 2451 /** 2452 * Adds a binding, There must not already be a binding 2453 * with the same name. 2454 * 2455 * @param b The binding. Passed by move. 2456 * @param status Input/output error code. Set to U_DUPLICATE_DECLARATION_ERROR 2457 * if `addBinding()` was previously called with a binding 2458 * with the same variable name as `b`. 2459 * 2460 * @internal ICU 75 technology preview 2461 * @deprecated This API is for technology preview only. 2462 */ 2463 Builder& addBinding(Binding&& b, UErrorCode& status); 2464 /** 2465 * Adds a selector expression. Copies `expression`. 2466 * If a pattern was previously set, clears the pattern. 2467 * 2468 * @param selector Expression to add as a selector. Passed by move. 2469 * @param errorCode Input/output error code 2470 * @return A reference to the builder. 2471 * 2472 * @internal ICU 75 technology preview 2473 * @deprecated This API is for technology preview only. 2474 */ 2475 Builder& addSelector(Expression&& selector, UErrorCode& errorCode) noexcept; 2476 /** 2477 * Adds a single variant. 2478 * If a pattern was previously set using `setPattern()`, clears the pattern. 2479 * 2480 * @param keys Keys for the variant. Passed by move. 2481 * @param pattern Pattern for the variant. Passed by move. 2482 * @param errorCode Input/output error code 2483 * @return A reference to the builder. 2484 * 2485 * @internal ICU 75 technology preview 2486 * @deprecated This API is for technology preview only. 2487 */ 2488 Builder& addVariant(SelectorKeys&& keys, Pattern&& pattern, UErrorCode& errorCode) noexcept; 2489 /** 2490 * Sets the body of the message as a pattern. 2491 * If selectors and/or variants were previously set, clears them. 2492 * 2493 * @param pattern Pattern to represent the body of the message. 2494 * Passed by move. 2495 * @return A reference to the builder. 2496 * 2497 * @internal ICU 75 technology preview 2498 * @deprecated This API is for technology preview only. 2499 */ 2500 Builder& setPattern(Pattern&& pattern); 2501 /** 2502 * Constructs a new immutable data model. 2503 * If `setPattern()` has not been called and if `addSelector()` and 2504 * `addVariant()` were not each called at least once, 2505 * `status` is set to `U_INVALID_STATE_ERROR`. 2506 * If `addSelector()` was called and `addVariant()` was never called, 2507 * or vice versa, then `status` is set to U_INVALID_STATE_ERROR. 2508 * Otherwise, either a Pattern or Selectors message is constructed 2509 * based on the pattern that was previously set, or selectors and variants 2510 * that were previously set. 2511 * 2512 * The builder object (`this`) can still be used after calling `build()`. 2513 * 2514 * @param status Input/output error code. 2515 * @return The new MFDataModel 2516 * 2517 * @internal ICU 75 technology preview 2518 * @deprecated This API is for technology preview only. 2519 */ 2520 MFDataModel build(UErrorCode& status) const noexcept; 2521 /** 2522 * Default constructor. 2523 * Returns a Builder with no pattern or selectors set. 2524 * Either `setPattern()` or both `addSelector()` and 2525 * `addVariant()` must be called before calling `build()` 2526 * on the resulting builder. 2527 * 2528 * @param status Input/output error code. 2529 * 2530 * @internal ICU 75 technology preview 2531 * @deprecated This API is for technology preview only. 2532 */ 2533 Builder(UErrorCode& status); 2534 /** 2535 * Destructor. 2536 * 2537 * @internal ICU 75 technology preview 2538 * @deprecated This API is for technology preview only. 2539 */ 2540 virtual ~Builder(); 2541 Builder(const Builder&) = delete; 2542 Builder& operator=(const Builder&) = delete; 2543 Builder(Builder&&) = delete; 2544 Builder& operator=(Builder&&) = delete; 2545 }; // class Builder 2546 2547 private: 2548 friend class Checker; 2549 friend class MessageFormatter; 2550 friend class Serializer; 2551 2552 Pattern empty; // Provided so that `getPattern()` can return a result 2553 // if called on a selectors message 2554 bool hasPattern() const { return std::holds_alternative<Pattern>(body); } 2555 2556 bool bogus = false; // Set if a copy constructor fails 2557 2558 // A message body is either a matcher (selector list and variant list), 2559 // or a single pattern 2560 std::variant<Matcher, Pattern> body; 2561 2562 // Bindings for local variables 2563 /* const */ LocalArray<Binding> bindings; 2564 int32_t bindingsLen = 0; 2565 2566 const Binding* getLocalVariablesInternal() const; 2567 const Expression* getSelectorsInternal() const; 2568 const Variant* getVariantsInternal() const; 2569 2570 int32_t numSelectors() const { 2571 const Matcher* matcher = std::get_if<Matcher>(&body); 2572 return (matcher == nullptr ? 0 : matcher->numSelectors); 2573 } 2574 int32_t numVariants() const { 2575 const Matcher* matcher = std::get_if<Matcher>(&body); 2576 return (matcher == nullptr ? 0 : matcher->numVariants); 2577 } 2578 2579 // Helper 2580 void initBindings(const Binding*); 2581 2582 MFDataModel(const Builder& builder, UErrorCode&) noexcept; 2583 }; // class MFDataModel 2584 2585 } // namespace message2 2586 2587 U_NAMESPACE_END 2588 2589 #endif // U_HIDE_DEPRECATED_API 2590 2591 #endif /* #if !UCONFIG_NO_MF2 */ 2592 2593 #endif /* #if !UCONFIG_NO_FORMATTING */ 2594 2595 #endif /* U_SHOW_CPLUSPLUS_API */ 2596 2597 #endif // MESSAGEFORMAT_DATA_MODEL_H 2598 2599 // eof 2600
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|