messageformat2_data_model.h (98929B)
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 MESSAGEFORMAT_DATA_MODEL_H 7 #define MESSAGEFORMAT_DATA_MODEL_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/localpointer.h" 18 #include "unicode/messageformat2_data_model_names.h" 19 20 #ifndef U_HIDE_DEPRECATED_API 21 22 #include <algorithm> 23 #include <cstddef> 24 #include <iterator> 25 #include <optional> 26 #include <variant> 27 #include <vector> 28 29 U_NAMESPACE_BEGIN 30 31 class UVector; 32 33 // Helpers 34 35 // Note: this _must_ be declared `inline` or else gcc will generate code 36 // for its instantiations, which needs to be avoided because it returns 37 // a std::vector 38 template<typename T> 39 static inline std::vector<T> toStdVector(const T* arr, int32_t len) { 40 std::vector<T> result; 41 for (int32_t i = 0; i < len; i++) { 42 result.push_back(arr[i]); 43 } 44 return result; 45 } 46 47 #if defined(U_REAL_MSVC) 48 #pragma warning(push) 49 // Ignore warning 4251 as these templates are instantiated later in this file, 50 // after the classes used to instantiate them have been defined. 51 #pragma warning(disable: 4251) 52 #endif 53 54 namespace message2 { 55 class Checker; 56 class MessageFormatter; 57 class Parser; 58 class Serializer; 59 60 61 namespace data_model { 62 class Binding; 63 class Literal; 64 class Operator; 65 class MFDataModel; 66 67 /** 68 * The `Literal` class corresponds to the `literal` nonterminal in the MessageFormat 2 grammar, 69 * https://github.com/unicode-org/message-format-wg/blob/main/spec/message.abnf and the 70 * `Literal` interface defined in 71 * // https://github.com/unicode-org/message-format-wg/blob/main/spec/data-model.md#expressions 72 * 73 * `Literal` is immutable, copyable and movable. 74 * 75 * @internal ICU 75 technology preview 76 * @deprecated This API is for technology preview only. 77 */ 78 class U_I18N_API Literal : public UObject { 79 public: 80 /** 81 * Returns the quoted representation of this literal (enclosed in '|' characters) 82 * 83 * @return A string representation of the literal enclosed in quote characters. 84 * 85 * @internal ICU 75 technology preview 86 * @deprecated This API is for technology preview only. 87 */ 88 UnicodeString quoted() const; 89 /** 90 * Returns the parsed string contents of this literal. 91 * 92 * @return A string representation of this literal. 93 * 94 * @internal ICU 75 technology preview 95 * @deprecated This API is for technology preview only. 96 */ 97 const UnicodeString& unquoted() const; 98 /** 99 * Determines if this literal appeared as a quoted literal in the message. 100 * 101 * @return true if and only if this literal appeared as a quoted literal in the 102 * message. 103 * 104 * @internal ICU 75 technology preview 105 * @deprecated This API is for technology preview only. 106 */ 107 UBool isQuoted() const { return thisIsQuoted; } 108 /** 109 * Literal constructor. 110 * 111 * @param q True if and only if this literal was parsed with the `quoted` nonterminal 112 * (appeared enclosed in '|' characters in the message text). 113 * @param s The string contents of this literal; escape sequences are assumed to have 114 * been interpreted already. 115 * 116 * @internal ICU 75 technology preview 117 * @deprecated This API is for technology preview only. 118 */ 119 Literal(UBool q, const UnicodeString& s) : thisIsQuoted(q), contents(s) {} 120 /** 121 * Copy constructor. 122 * 123 * @internal ICU 75 technology preview 124 * @deprecated This API is for technology preview only. 125 */ 126 Literal(const Literal& other) : thisIsQuoted(other.thisIsQuoted), contents(other.contents) {} 127 /** 128 * Non-member swap function. 129 * @param l1 will get l2's contents 130 * @param l2 will get l1's contents 131 * 132 * @internal ICU 75 technology preview 133 * @deprecated This API is for technology preview only. 134 */ 135 friend inline void swap(Literal& l1, Literal& l2) noexcept { 136 using std::swap; 137 138 swap(l1.thisIsQuoted, l2.thisIsQuoted); 139 swap(l1.contents, l2.contents); 140 } 141 /** 142 * Assignment operator. 143 * 144 * @internal ICU 75 technology preview 145 * @deprecated This API is for technology preview only. 146 */ 147 Literal& operator=(Literal) noexcept; 148 /** 149 * Default constructor. 150 * Puts the Literal into a valid but undefined state. 151 * 152 * @internal ICU 75 technology preview 153 * @deprecated This API is for technology preview only. 154 */ 155 Literal() = default; 156 /** 157 * Less than operator. Compares `this.stringContents()` with 158 * `other.stringContents()`. This method is used in representing 159 * the mapping from key lists to patterns in a message with variants, 160 * and is not expected to be useful otherwise. 161 * 162 * @param other The Literal to compare to this one. 163 * @return true if the parsed string corresponding to this `Literal` 164 * is less than the parsed string corresponding to the other `Literal` 165 * (according to `UnicodeString`'s less-than operator). 166 * Returns false otherwise. 167 * 168 * @internal ICU 75 technology preview 169 * @deprecated This API is for technology preview only. 170 */ 171 bool operator<(const Literal& other) const; 172 /** 173 * Equality operator. Compares `this.stringContents()` with 174 * `other.stringContents()`. This method is used in representing 175 * the mapping from key lists to patterns in a message with variants, 176 * and is not expected to be useful otherwise. 177 * 178 * @param other The Literal to compare to this one. 179 * @return true if the parsed string corresponding to this `Literal` 180 * equals the parsed string corresponding to the other `Literal` 181 * (according to `UnicodeString`'s equality operator). 182 * Returns false otherwise. 183 * 184 * @internal ICU 75 technology preview 185 * @deprecated This API is for technology preview only. 186 */ 187 bool operator==(const Literal& other) const; 188 /** 189 * Destructor. 190 * 191 * @internal ICU 75 technology preview 192 * @deprecated This API is for technology preview only. 193 */ 194 virtual ~Literal(); 195 196 private: 197 /* const */ bool thisIsQuoted = false; 198 /* const */ UnicodeString contents; 199 }; 200 201 /** 202 * The `Operand` class corresponds to the `operand` nonterminal in the MessageFormat 2 grammar, 203 * https://github.com/unicode-org/message-format-wg/blob/main/spec/message.abnf . 204 * It represents a `Literal | VariableRef` -- see the `operand?` field of the `FunctionRef` 205 * interface defined at: 206 * https://github.com/unicode-org/message-format-wg/blob/main/spec/data-model.md#expressions 207 * with the difference that it can also represent a null operand (the absent operand in an 208 * `annotation` with no operand). 209 * 210 * `Operand` is immutable and is copyable and movable. 211 * 212 * @internal ICU 75 technology preview 213 * @deprecated This API is for technology preview only. 214 */ 215 class U_I18N_API_CLASS Operand : public UObject { 216 public: 217 /** 218 * Determines if this operand represents a variable. 219 * 220 * @return True if and only if the operand is a variable. 221 * 222 * @internal ICU 75 technology preview 223 * @deprecated This API is for technology preview only. 224 */ 225 U_I18N_API UBool isVariable() const; 226 /** 227 * Determines if this operand represents a literal. 228 * 229 * @return True if and only if the operand is a literal. 230 * 231 * @internal ICU 75 technology preview 232 * @deprecated This API is for technology preview only. 233 */ 234 U_I18N_API UBool isLiteral() const; 235 /** 236 * Determines if this operand is the null operand. 237 * 238 * @return True if and only if the operand is the null operand. 239 * 240 * @internal ICU 75 technology preview 241 * @deprecated This API is for technology preview only. 242 */ 243 U_I18N_API virtual UBool isNull() const; 244 /** 245 * Returns a reference to this operand's variable name. 246 * Precondition: isVariable() 247 * 248 * @return A reference to the name of the variable 249 * 250 * @internal ICU 75 technology preview 251 * @deprecated This API is for technology preview only. 252 */ 253 U_I18N_API const UnicodeString& asVariable() const; 254 /** 255 * Returns a reference to this operand's literal contents. 256 * Precondition: isLiteral() 257 * 258 * @return A reference to the literal 259 * 260 * @internal ICU 75 technology preview 261 * @deprecated This API is for technology preview only. 262 */ 263 U_I18N_API const Literal& asLiteral() const; 264 /** 265 * Default constructor. 266 * Creates a null Operand. 267 * 268 * @internal ICU 75 technology preview 269 * @deprecated This API is for technology preview only. 270 */ 271 U_I18N_API Operand() : contents(std::nullopt) {} 272 /** 273 * Variable operand constructor. 274 * 275 * @param v The variable name; an operand corresponding 276 * to a reference to `v` is returned. 277 * 278 * @internal ICU 75 technology preview 279 * @deprecated This API is for technology preview only. 280 */ 281 U_I18N_API explicit Operand(const UnicodeString& v) : contents(VariableName(v)) {} 282 /** 283 * Literal operand constructor. 284 * 285 * @param l The literal to use for this operand; an operand 286 * corresponding to `l` is returned. 287 * 288 * @internal ICU 75 technology preview 289 * @deprecated This API is for technology preview only. 290 */ 291 U_I18N_API explicit Operand(const Literal& l) : contents(l) {} 292 /** 293 * Non-member swap function. 294 * @param o1 will get o2's contents 295 * @param o2 will get o1's contents 296 * 297 * @internal ICU 75 technology preview 298 * @deprecated This API is for technology preview only. 299 */ 300 U_I18N_API friend inline void swap(Operand& o1, Operand& o2) noexcept { 301 using std::swap; 302 (void) o1; 303 (void) o2; 304 swap(o1.contents, o2.contents); 305 } 306 /** 307 * Assignment operator. 308 * 309 * @internal ICU 75 technology preview 310 * @deprecated This API is for technology preview only. 311 */ 312 U_I18N_API virtual Operand& operator=(Operand) noexcept; 313 /** 314 * Copy constructor. 315 * 316 * @internal ICU 75 technology preview 317 * @deprecated This API is for technology preview only. 318 */ 319 U_I18N_API Operand(const Operand&); 320 /** 321 * Destructor. 322 * 323 * @internal ICU 75 technology preview 324 * @deprecated This API is for technology preview only. 325 */ 326 U_I18N_API virtual ~Operand(); 327 private: 328 std::optional<std::variant<VariableName, Literal>> contents; 329 }; // class Operand 330 331 /** 332 * The `Key` class corresponds to the `key` nonterminal in the MessageFormat 2 grammar, 333 * https://github.com/unicode-org/message-format-wg/blob/main/spec/message.abnf . 334 * It also corresponds to 335 * the `Literal | CatchallKey` that is the 336 * element type of the `keys` array in the `Variant` interface 337 * defined in https://github.com/unicode-org/message-format-wg/blob/main/spec/data-model.md#messages 338 * 339 * A key is either a literal or the wildcard symbol (represented in messages as '*') 340 * 341 * `Key` is immutable, copyable and movable. 342 * 343 * @internal ICU 75 technology preview 344 * @deprecated This API is for technology preview only. 345 */ 346 class U_I18N_API_CLASS Key : public UObject { 347 public: 348 /** 349 * Determines if this is a wildcard key 350 * 351 * @return True if and only if this is the wildcard key 352 * 353 * @internal ICU 75 technology preview 354 * @deprecated This API is for technology preview only. 355 */ 356 U_I18N_API UBool isWildcard() const { return !contents.has_value(); } 357 /** 358 * Returns the contents of this key as a literal. 359 * Precondition: !isWildcard() 360 * 361 * @return The literal contents of the key 362 * 363 * @internal ICU 75 technology preview 364 * @deprecated This API is for technology preview only. 365 */ 366 U_I18N_API const Literal& asLiteral() const; 367 /** 368 * Copy constructor. 369 * 370 * @internal ICU 75 technology preview 371 * @deprecated This API is for technology preview only. 372 */ 373 U_I18N_API Key(const Key& other) : contents(other.contents) {} 374 /** 375 * Wildcard constructor; constructs a Key representing the 376 * catchall or wildcard key, '*'. 377 * 378 * @internal ICU 75 technology preview 379 * @deprecated This API is for technology preview only. 380 */ 381 U_I18N_API Key() : contents(std::nullopt) {} 382 /** 383 * Literal key constructor. 384 * 385 * @param lit A Literal to use for this key. The result matches the 386 * literal `lit`. 387 * 388 * @internal ICU 75 technology preview 389 * @deprecated This API is for technology preview only. 390 */ 391 U_I18N_API explicit Key(const Literal& lit) : contents(lit) {} 392 /** 393 * Non-member swap function. 394 * @param k1 will get k2's contents 395 * @param k2 will get k1's contents 396 * 397 * @internal ICU 75 technology preview 398 * @deprecated This API is for technology preview only. 399 */ 400 U_I18N_API friend inline void swap(Key& k1, Key& k2) noexcept { 401 using std::swap; 402 403 swap(k1.contents, k2.contents); 404 } 405 /** 406 * Assignment operator 407 * 408 * @internal ICU 75 technology preview 409 * @deprecated This API is for technology preview only. 410 */ 411 U_I18N_API Key& operator=(Key) noexcept; 412 /** 413 * Less than operator. Compares the literal of `this` with the literal of `other`. 414 * This method is used in representing the mapping from key lists to patterns 415 * in a message with variants, and is not expected to be useful otherwise. 416 * 417 * @param other The Key to compare to this one. 418 * @return true if the two `Key`s are not wildcards and if `this.asLiteral()` 419 * < `other.asLiteral()`. 420 * Returns false otherwise. 421 * 422 * @internal ICU 75 technology preview 423 * @deprecated This API is for technology preview only. 424 */ 425 U_I18N_API bool operator<(const Key& other) const; 426 /** 427 * Equality operator. Compares the literal of `this` with the literal of `other`. 428 * This method is used in representing the mapping from key lists to patterns 429 * in a message with variants, and is not expected to be useful otherwise. 430 * 431 * @param other The Key to compare to this one. 432 * @return true if either both `Key`s are wildcards, or `this.asLiteral()` 433 * == `other.asLiteral()`. 434 * Returns false otherwise. 435 * 436 * @internal ICU 75 technology preview 437 * @deprecated This API is for technology preview only. 438 */ 439 U_I18N_API bool operator==(const Key& other) const; 440 /** 441 * Destructor. 442 * 443 * @internal ICU 75 technology preview 444 * @deprecated This API is for technology preview only. 445 */ 446 U_I18N_API virtual ~Key(); 447 private: 448 /* const */ std::optional<Literal> contents; 449 }; // class Key 450 451 /** 452 * The `SelectorKeys` class represents the key list for a single variant. 453 * It corresponds to the `keys` array in the `Variant` interface 454 * defined in https://github.com/unicode-org/message-format-wg/blob/main/spec/data-model.md#messages 455 * 456 * `SelectorKeys` is immutable, copyable and movable. 457 * 458 * @internal ICU 75 technology preview 459 * @deprecated This API is for technology preview only. 460 */ 461 class U_I18N_API_CLASS SelectorKeys : public UObject { 462 public: 463 /** 464 * Returns the underlying list of keys. 465 * 466 * @return The list of keys for this variant. 467 * Returns an empty list if allocating this `SelectorKeys` 468 * object previously failed. 469 * 470 * @internal ICU 75 technology preview 471 * @deprecated This API is for technology preview only. 472 */ 473 U_I18N_API std::vector<Key> getKeys() const { 474 return toStdVector<Key>(keys.getAlias(), len); 475 } 476 /** 477 * The mutable `SelectorKeys::Builder` class allows the key list to be constructed 478 * one key at a time. 479 * 480 * Builder is not copyable or movable. 481 * 482 * @internal ICU 75 technology preview 483 * @deprecated This API is for technology preview only. 484 */ 485 class U_I18N_API Builder : public UMemory { 486 private: 487 friend class SelectorKeys; 488 UVector* keys; // This is a raw pointer and not a LocalPointer<UVector> to avoid undefined behavior warnings, 489 // since UVector is forward-declared 490 // The vector owns its elements 491 public: 492 /** 493 * Adds a single key to the list. 494 * 495 * @param key The key to be added. Passed by move 496 * @param status Input/output error code 497 * @return A reference to the builder. 498 * 499 * @internal ICU 75 technology preview 500 * @deprecated This API is for technology preview only. 501 */ 502 Builder& add(Key&& key, UErrorCode& status) noexcept; 503 /** 504 * Constructs a new immutable `SelectorKeys` using the list of keys 505 * set with previous `add()` calls. 506 * 507 * The builder object (`this`) can still be used after calling `build()`. 508 * 509 * @param status Input/output error code 510 * @return The new SelectorKeys object 511 * 512 * @internal ICU 75 technology preview 513 * @deprecated This API is for technology preview only. 514 */ 515 SelectorKeys build(UErrorCode& status) const; 516 /** 517 * Default constructor. 518 * Returns a Builder with an empty list of keys. 519 * 520 * @param status Input/output error code 521 * 522 * @internal ICU 75 technology preview 523 * @deprecated This API is for technology preview only. 524 */ 525 Builder(UErrorCode& status); 526 /** 527 * Destructor. 528 * 529 * @internal ICU 75 technology preview 530 * @deprecated This API is for technology preview only. 531 */ 532 virtual ~Builder(); 533 Builder(const Builder&) = delete; 534 Builder& operator=(const Builder&) = delete; 535 Builder(Builder&&) = delete; 536 Builder& operator=(Builder&&) = delete; 537 }; // class SelectorKeys::Builder 538 /** 539 * Less than operator. Compares the two key lists lexicographically. 540 * This method makes it possible for a `SelectorKeys` to be used as a map 541 * key, which allows variants to be represented as a map. It is not expected 542 * to be useful otherwise. 543 * 544 * @param other The SelectorKeys to compare to this one. 545 * @return true if `this` is less than `other`, comparing the two key lists 546 * lexicographically. 547 * Returns false otherwise. 548 * 549 * @internal ICU 75 technology preview 550 * @deprecated This API is for technology preview only. 551 */ 552 U_I18N_API bool operator<(const SelectorKeys& other) const; 553 /** 554 * Default constructor. 555 * Puts the SelectorKeys into a valid but undefined state. 556 * 557 * @internal ICU 75 technology preview 558 * @deprecated This API is for technology preview only. 559 */ 560 U_I18N_API SelectorKeys() : len(0) {} 561 /** 562 * Non-member swap function. 563 * @param s1 will get s2's contents 564 * @param s2 will get s1's contents 565 * 566 * @internal ICU 75 technology preview 567 * @deprecated This API is for technology preview only. 568 */ 569 U_I18N_API friend inline void swap(SelectorKeys& s1, SelectorKeys& s2) noexcept { 570 using std::swap; 571 572 swap(s1.len, s2.len); 573 swap(s1.keys, s2.keys); 574 } 575 /** 576 * Copy constructor. 577 * 578 * @internal ICU 75 technology preview 579 * @deprecated This API is for technology preview only. 580 */ 581 U_I18N_API SelectorKeys(const SelectorKeys& other); 582 /** 583 * Assignment operator. 584 * 585 * @internal ICU 75 technology preview 586 * @deprecated This API is for technology preview only. 587 */ 588 U_I18N_API SelectorKeys& operator=(SelectorKeys other) noexcept; 589 /** 590 * Destructor. 591 * 592 * @internal ICU 75 technology preview 593 * @deprecated This API is for technology preview only. 594 */ 595 U_I18N_API virtual ~SelectorKeys(); 596 private: 597 friend class Builder; 598 friend class message2::Checker; 599 friend class message2::MessageFormatter; 600 friend class message2::Serializer; 601 602 /* const */ LocalArray<Key> keys; 603 /* const */ int32_t len; 604 605 const Key* getKeysInternal() const; 606 SelectorKeys(const UVector& ks, UErrorCode& status); 607 }; // class SelectorKeys 608 609 class Operator; 610 611 /** 612 * An `Option` pairs an option name with an Operand. 613 * 614 * `Option` is immutable, copyable and movable. 615 * 616 * @internal ICU 75 technology preview 617 * @deprecated This API is for technology preview only. 618 */ 619 class U_I18N_API Option : public UObject { 620 public: 621 /** 622 * Accesses the right-hand side of the option. 623 * 624 * @return A reference to the operand. 625 * 626 * @internal ICU 75 technology preview 627 * @deprecated This API is for technology preview only. 628 */ 629 const Operand& getValue() const { return rand; } 630 /** 631 * Accesses the left-hand side of the option. 632 * 633 * @return A reference to the option name. 634 * 635 * @internal ICU 75 technology preview 636 * @deprecated This API is for technology preview only. 637 */ 638 const UnicodeString& getName() const { return name; } 639 /** 640 * Constructor. Returns an `Option` representing the 641 * named option "name=rand". 642 * 643 * @param n The name of the option. 644 * @param r The value of the option. 645 * 646 * @internal ICU 75 technology preview 647 * @deprecated This API is for technology preview only. 648 */ 649 Option(const UnicodeString& n, Operand&& r) : name(n), rand(std::move(r)) {} 650 /** 651 * Default constructor. 652 * Returns an Option in a valid but undefined state. 653 * 654 * @internal ICU 75 technology preview 655 * @deprecated This API is for technology preview only. 656 */ 657 Option() {} 658 /** 659 * Non-member swap function. 660 * @param o1 will get o2's contents 661 * @param o2 will get o1's contents 662 * 663 * @internal ICU 75 technology preview 664 * @deprecated This API is for technology preview only. 665 */ 666 friend inline void swap(Option& o1, Option& o2) noexcept { 667 using std::swap; 668 669 swap(o1.name, o2.name); 670 swap(o1.rand, o2.rand); 671 } 672 /** 673 * Copy constructor. 674 * 675 * @internal ICU 75 technology preview 676 * @deprecated This API is for technology preview only. 677 */ 678 Option(const Option& other); 679 /** 680 * Assignment operator 681 * 682 * @internal ICU 75 technology preview 683 * @deprecated This API is for technology preview only. 684 */ 685 Option& operator=(Option other) noexcept; 686 /** 687 * Destructor. 688 * 689 * @internal ICU 75 technology preview 690 * @deprecated This API is for technology preview only. 691 */ 692 virtual ~Option(); 693 private: 694 /* const */ UnicodeString name; 695 /* const */ Operand rand; 696 }; // class Option 697 698 // Internal only 699 #ifndef U_IN_DOXYGEN 700 // Options 701 // This is a wrapper class around a vector of options that provides lookup operations 702 class U_I18N_API_CLASS OptionMap : public UObject { 703 public: 704 U_I18N_API int32_t size() const; 705 // Needs to take an error code b/c an earlier copy might have failed 706 U_I18N_API const Option& getOption(int32_t, UErrorCode&) const; 707 U_I18N_API friend inline void swap(OptionMap& m1, OptionMap& m2) noexcept { 708 using std::swap; 709 710 swap(m1.bogus, m2.bogus); 711 swap(m1.options, m2.options); 712 swap(m1.len, m2.len); 713 } 714 U_I18N_API OptionMap() : len(0) {} 715 U_I18N_API OptionMap(const OptionMap&); 716 U_I18N_API OptionMap& operator=(OptionMap); 717 U_I18N_API std::vector<Option> getOptions() const { 718 return toStdVector<Option>(options.getAlias(), len); 719 } 720 U_I18N_API OptionMap(const UVector&, UErrorCode&); 721 U_I18N_API OptionMap(Option*, int32_t); 722 U_I18N_API virtual ~OptionMap(); 723 724 class U_I18N_API Builder : public UObject { 725 private: 726 UVector* options; 727 bool checkDuplicates = true; 728 public: 729 Builder& add(Option&& opt, UErrorCode&); 730 Builder(UErrorCode&); 731 static Builder attributes(UErrorCode&); 732 // As this class is private, build() is destructive 733 OptionMap build(UErrorCode&); 734 friend inline void swap(Builder& m1, Builder& m2) noexcept { 735 using std::swap; 736 737 swap(m1.options, m2.options); 738 swap(m1.checkDuplicates, m2.checkDuplicates); 739 } 740 Builder(Builder&&); 741 Builder(const Builder&) = delete; 742 Builder& operator=(Builder) noexcept; 743 virtual ~Builder(); 744 }; // class OptionMap::Builder 745 private: 746 friend class message2::Serializer; 747 748 bool bogus = false; 749 LocalArray<Option> options; 750 int32_t len; 751 }; // class OptionMap 752 #endif 753 754 /** 755 * The `Operator` class corresponds to the `FunctionRef` type in the 756 * `Expression` interface defined in 757 * https://github.com/unicode-org/message-format-wg/blob/main/spec/data-model.md#patterns 758 * 759 * It represents the annotation that an expression can have: a function name paired 760 * with a map from option names to operands (possibly empty). 761 * 762 * `Operator` is immutable, copyable and movable. 763 * 764 * @internal ICU 75 technology preview 765 * @deprecated This API is for technology preview only. 766 */ 767 class U_I18N_API Operator : public UObject { 768 public: 769 /** 770 * Accesses the function name. 771 * 772 * @return The function name of this operator. 773 * 774 * @internal ICU 75 technology preview 775 * @deprecated This API is for technology preview only. 776 */ 777 const FunctionName& getFunctionName() const; 778 /** 779 * Accesses function options. 780 * 781 * @return A vector of function options for this operator. 782 * 783 * @internal ICU 75 technology preview 784 * @deprecated This API is for technology preview only. 785 */ 786 std::vector<Option> getOptions() const { 787 return options.getOptions(); 788 } 789 /** 790 * The mutable `Operator::Builder` class allows the operator to be constructed 791 * incrementally. 792 * 793 * Builder is not copyable or movable. 794 * 795 * @internal ICU 75 technology preview 796 * @deprecated This API is for technology preview only. 797 */ 798 class U_I18N_API Builder : public UMemory { 799 private: 800 friend class Operator; 801 FunctionName functionName; 802 OptionMap::Builder options; 803 public: 804 /** 805 * Sets this operator to be a function annotation and sets its name 806 * to `func`. 807 * 808 * @param func The function name. 809 * @return A reference to the builder. 810 * 811 * @internal ICU 75 technology preview 812 * @deprecated This API is for technology preview only. 813 */ 814 Builder& setFunctionName(FunctionName&& func); 815 /** 816 * Sets this operator to be a function annotation and adds a 817 * single option. 818 * 819 * @param key The name of the option. 820 * @param value The value (right-hand side) of the option. 821 * @param status Input/output error code. 822 * @return A reference to the builder. 823 * 824 * @internal ICU 75 technology preview 825 * @deprecated This API is for technology preview only. 826 */ 827 Builder& addOption(const UnicodeString &key, Operand&& value, UErrorCode& status) noexcept; 828 /** 829 * Constructs a new immutable `Operator` using the 830 * function name and options that were previously set. 831 * 832 * The builder object (`this`) can still be used after calling `build()`. 833 * 834 * The `build()` method is non-const for internal implementation reasons, 835 * but is observably const. 836 * 837 * @param status Input/output error code. 838 * @return The new Operator 839 * 840 * @internal ICU 75 technology preview 841 * @deprecated This API is for technology preview only. 842 */ 843 Operator build(UErrorCode& status); 844 /** 845 * Default constructor. 846 * Returns a Builder with no function name or options set. 847 * 848 * @param status Input/output error code. 849 * 850 * @internal ICU 75 technology preview 851 * @deprecated This API is for technology preview only. 852 */ 853 Builder(UErrorCode& status); 854 /** 855 * Destructor. 856 * 857 * @internal ICU 75 technology preview 858 * @deprecated This API is for technology preview only. 859 */ 860 virtual ~Builder(); 861 Builder(const Builder&) = delete; 862 Builder& operator=(const Builder&) = delete; 863 Builder(Builder&&) = delete; 864 Builder& operator=(Builder&&) = delete; 865 }; // class Operator::Builder 866 /** 867 * Copy constructor. 868 * 869 * @internal ICU 75 technology preview 870 * @deprecated This API is for technology preview only. 871 */ 872 Operator(const Operator& other) noexcept; 873 /** 874 * Non-member swap function. 875 * @param o1 will get o2's contents 876 * @param o2 will get o1's contents 877 * 878 * @internal ICU 75 technology preview 879 * @deprecated This API is for technology preview only. 880 */ 881 friend inline void swap(Operator& o1, Operator& o2) noexcept { 882 using std::swap; 883 884 swap(o1.name, o2.name); 885 swap(o1.options, o2.options); 886 } 887 /** 888 * Assignment operator. 889 * 890 * @internal ICU 75 technology preview 891 * @deprecated This API is for technology preview only. 892 */ 893 Operator& operator=(Operator) noexcept; 894 /** 895 * Default constructor. 896 * Puts the Operator into a valid but undefined state. 897 * 898 * @internal ICU 75 technology preview 899 * @deprecated This API is for technology preview only. 900 */ 901 Operator() {} 902 /** 903 * Destructor. 904 * 905 * @internal ICU 75 technology preview 906 * @deprecated This API is for technology preview only. 907 */ 908 virtual ~Operator(); 909 private: 910 friend class Binding; 911 friend class Builder; 912 friend class message2::Checker; 913 friend class message2::MessageFormatter; 914 friend class message2::Serializer; 915 916 // Function call constructor 917 Operator(const FunctionName& f, const UVector& options, UErrorCode&); 918 919 const OptionMap& getOptionsInternal() const; 920 Operator(const FunctionName&, const OptionMap&); 921 922 /* const */ FunctionName name; 923 /* const */ OptionMap options; 924 }; // class Operator 925 926 // Internal only 927 typedef enum UMarkupType { 928 UMARKUP_OPEN = 0, 929 UMARKUP_CLOSE, 930 UMARKUP_STANDALONE, 931 UMARKUP_COUNT 932 } UMarkupType; 933 934 /** 935 * The `Markup` class corresponds to the `markup` nonterminal in the MessageFormat 2 936 * grammar and the `markup` interface defined in 937 * https://github.com/unicode-org/message-format-wg/blob/main/spec/data-model/message.json 938 * 939 * `Markup` is immutable, copyable and movable. 940 * 941 * @internal ICU 75 technology preview 942 * @deprecated This API is for technology preview only. 943 */ 944 class U_I18N_API Markup : public UObject { 945 public: 946 /** 947 * Checks if this markup is an opening tag. 948 * 949 * @return True if and only if this represents an opening tag. 950 * 951 * @internal ICU 75 technology preview 952 * @deprecated This API is for technology preview only. 953 */ 954 UBool isOpen() const { return (type == UMARKUP_OPEN); } 955 /** 956 * Checks if this markup is an closing tag. 957 * 958 * @return True if and only if this represents an closing tag. 959 * 960 * @internal ICU 75 technology preview 961 * @deprecated This API is for technology preview only. 962 */ 963 UBool isClose() const { return (type == UMARKUP_CLOSE); } 964 /** 965 * Checks if this markup is an standalone tag. 966 * 967 * @return True if and only if this represents a standalone tag. 968 * 969 * @internal ICU 75 technology preview 970 * @deprecated This API is for technology preview only. 971 */ 972 UBool isStandalone() const { return (type == UMARKUP_STANDALONE); } 973 /** 974 * Gets the name of this markup 975 * 976 * @return A reference to the string identifying the markup 977 * 978 * @internal ICU 75 technology preview 979 * @deprecated This API is for technology preview only. 980 */ 981 const UnicodeString& getName() const { return name; } 982 /** 983 * Gets the options of this markup 984 * 985 * @return A reference to the string identifying the markup 986 * 987 * @internal ICU 75 technology preview 988 * @deprecated This API is for technology preview only. 989 */ 990 std::vector<Option> getOptions() const { return options.getOptions(); } 991 /** 992 * Gets the attributes of this markup 993 * 994 * @return A vector of attributes 995 * 996 * @internal ICU 75 technology preview 997 * @deprecated This API is for technology preview only. 998 */ 999 std::vector<Option> getAttributes() const { return attributes.getOptions(); } 1000 /** 1001 * Default constructor. 1002 * Puts the Markup into a valid but undefined state. 1003 * 1004 * @internal ICU 75 technology preview 1005 * @deprecated This API is for technology preview only. 1006 */ 1007 Markup() {} 1008 /** 1009 * Destructor. 1010 * 1011 * @internal ICU 75 technology preview 1012 * @deprecated This API is for technology preview only. 1013 */ 1014 virtual ~Markup(); 1015 /** 1016 * The mutable `Markup::Builder` class allows the markup to be constructed 1017 * incrementally. 1018 * 1019 * Builder is not copyable or movable. 1020 * 1021 * @internal ICU 75 technology preview 1022 * @deprecated This API is for technology preview only. 1023 */ 1024 class U_I18N_API Builder : public UMemory { 1025 private: 1026 friend class Markup; 1027 1028 UnicodeString name; 1029 OptionMap::Builder options; 1030 OptionMap::Builder attributes; 1031 UMarkupType type = UMARKUP_COUNT; 1032 public: 1033 /** 1034 * Sets the name of this markup. 1035 * 1036 * @param n A string representing the name. 1037 * @return A reference to the builder. 1038 * 1039 * @internal ICU 75 technology preview 1040 * @deprecated This API is for technology preview only. 1041 */ 1042 Builder& setName(const UnicodeString& n) { name = n; return *this; } 1043 /** 1044 * Sets this to be an opening markup. 1045 * 1046 * @return A reference to the builder. 1047 * 1048 * @internal ICU 75 technology preview 1049 * @deprecated This API is for technology preview only. 1050 */ 1051 Builder& setOpen() { type = UMARKUP_OPEN; return *this; } 1052 /** 1053 * Sets this to be an closing markup. 1054 * 1055 * @return A reference to the builder. 1056 * 1057 * @internal ICU 75 technology preview 1058 * @deprecated This API is for technology preview only. 1059 */ 1060 Builder& setClose() { type = UMARKUP_CLOSE; return *this; } 1061 /** 1062 * Sets this to be a standalone markup. 1063 * 1064 * @return A reference to the builder. 1065 * 1066 * @internal ICU 75 technology preview 1067 * @deprecated This API is for technology preview only. 1068 */ 1069 Builder& setStandalone() { type = UMARKUP_STANDALONE; return *this; } 1070 /** 1071 * Adds a single option. 1072 * 1073 * @param key The name of the option. 1074 * @param value The value (right-hand side) of the option. 1075 * @param status Input/output error code. 1076 * @return A reference to the builder. 1077 * 1078 * @internal ICU 75 technology preview 1079 * @deprecated This API is for technology preview only. 1080 */ 1081 Builder& addOption(const UnicodeString &key, Operand&& value, UErrorCode& status); 1082 /** 1083 * Adds a single attribute. 1084 * 1085 * @param key The name of the attribute. 1086 * @param value The value (right-hand side) of the attribute. 1087 * @param status Input/output error code. 1088 * @return A reference to the builder. 1089 * 1090 * @internal ICU 75 technology preview 1091 * @deprecated This API is for technology preview only. 1092 */ 1093 Builder& addAttribute(const UnicodeString &key, Operand&& value, UErrorCode& status); 1094 /** 1095 * Constructs a new immutable `Markup` using the name and type 1096 * and (optionally) options and attributes that were previously set. 1097 * If `setName()` and at least one of `setOpen()`, `setClose()`, and `setStandalone()` 1098 * were not previously called, 1099 * then `status` is set to U_INVALID_STATE_ERROR. 1100 * 1101 * The builder object (`this`) can still be used after calling `build()`. 1102 * The `build()` method is non-const for internal implementation reasons, 1103 * but is observably const. 1104 * 1105 * @param status Input/output error code. 1106 * @return The new Markup. 1107 * 1108 * @internal ICU 75 technology preview 1109 * @deprecated This API is for technology preview only. 1110 */ 1111 Markup build(UErrorCode& status); 1112 /** 1113 * Default constructor. 1114 * Returns a Builder with no name, type, options, or attributes set. 1115 * 1116 * @param status Input/output error code. 1117 * 1118 * @internal ICU 75 technology preview 1119 * @deprecated This API is for technology preview only. 1120 */ 1121 Builder(UErrorCode& status); 1122 /** 1123 * Destructor. 1124 * 1125 * @internal ICU 75 technology preview 1126 * @deprecated This API is for technology preview only. 1127 */ 1128 virtual ~Builder(); 1129 Builder(const Builder&) = delete; 1130 Builder& operator=(const Builder&) = delete; 1131 Builder(Builder&&) = delete; 1132 Builder& operator=(Builder&&) = delete; 1133 }; // class Markup::Builder 1134 1135 private: 1136 friend class Builder; 1137 friend class message2::Serializer; 1138 1139 UMarkupType type; 1140 UnicodeString name; 1141 OptionMap options; 1142 OptionMap attributes; 1143 const OptionMap& getOptionsInternal() const { return options; } 1144 const OptionMap& getAttributesInternal() const { return attributes; } 1145 Markup(UMarkupType, UnicodeString, OptionMap&&, OptionMap&&); 1146 }; // class Markup 1147 1148 /** 1149 * The `Expression` class corresponds to the `expression` nonterminal in the MessageFormat 2 1150 * grammar and the `Expression` interface defined in 1151 * https://github.com/unicode-org/message-format-wg/blob/main/spec/data-model.md#patterns 1152 * 1153 * It represents either an operand with no annotation; an annotation with no operand; 1154 * or an operand annotated with an annotation. 1155 * 1156 * `Expression` is immutable, copyable and movable. 1157 * 1158 * @internal ICU 75 technology preview 1159 * @deprecated This API is for technology preview only. 1160 */ 1161 class U_I18N_API_CLASS Expression : public UObject { 1162 public: 1163 /** 1164 * Checks if this expression is an annotation 1165 * with no operand. 1166 * 1167 * @return True if and only if the expression has 1168 * an annotation and has no operand. 1169 * 1170 * @internal ICU 75 technology preview 1171 * @deprecated This API is for technology preview only. 1172 */ 1173 U_I18N_API UBool isStandaloneAnnotation() const; 1174 /** 1175 * Checks if this expression has a function 1176 * annotation (with or without an operand). 1177 * 1178 * @return True if and only if the expression has an annotation 1179 * that is a function. 1180 * 1181 * @internal ICU 75 technology preview 1182 * @deprecated This API is for technology preview only. 1183 */ 1184 U_I18N_API UBool isFunctionCall() const; 1185 /** 1186 * Accesses the function 1187 * annotating this expression. 1188 * If !(isFunctionCall()), sets 1189 * `status` to U_INVALID_STATE_ERROR. 1190 * 1191 * @param status Input/output error code. 1192 * @return A non-owned pointer to the operator of this expression, 1193 * which does not outlive the expression. 1194 * 1195 * @internal ICU 75 technology preview 1196 * @deprecated This API is for technology preview only. 1197 */ 1198 U_I18N_API const Operator* getOperator(UErrorCode& status) const; 1199 /** 1200 * Accesses the operand of this expression. 1201 * 1202 * @return A reference to the operand of this expression, 1203 * which may be the null operand. 1204 * 1205 * @internal ICU 75 technology preview 1206 * @deprecated This API is for technology preview only. 1207 */ 1208 U_I18N_API const Operand& getOperand() const; 1209 /** 1210 * Gets the attributes of this expression 1211 * 1212 * @return A vector of attributes 1213 * 1214 * @internal ICU 75 technology preview 1215 * @deprecated This API is for technology preview only. 1216 */ 1217 U_I18N_API std::vector<Option> getAttributes() const { return attributes.getOptions(); } 1218 /** 1219 * The mutable `Expression::Builder` class allows the operator to be constructed 1220 * incrementally. 1221 * 1222 * Builder is not copyable or movable. 1223 * 1224 * @internal ICU 75 technology preview 1225 * @deprecated This API is for technology preview only. 1226 */ 1227 class U_I18N_API Builder : public UMemory { 1228 private: 1229 friend class Expression; 1230 1231 bool hasOperand = false; 1232 bool hasOperator = false; 1233 Operand rand; 1234 Operator rator; 1235 OptionMap::Builder attributes; 1236 public: 1237 /** 1238 * Sets the operand of this expression. 1239 * 1240 * @param rAnd The operand to set. Passed by move. 1241 * @return A reference to the builder. 1242 * 1243 * @internal ICU 75 technology preview 1244 * @deprecated This API is for technology preview only. 1245 */ 1246 Builder& setOperand(Operand&& rAnd); 1247 /** 1248 * Sets the operator of this expression. 1249 * 1250 * @param rAtor The operator to set. Passed by move. 1251 * @return A reference to the builder. 1252 * 1253 * @internal ICU 75 technology preview 1254 * @deprecated This API is for technology preview only. 1255 */ 1256 Builder& setOperator(Operator&& rAtor); 1257 /** 1258 * Adds a single attribute. 1259 * 1260 * @param key The name of the attribute. 1261 * @param value The value (right-hand side) of the attribute. 1262 * @param status Input/output error code. 1263 * @return A reference to the builder. 1264 * 1265 * @internal ICU 75 technology preview 1266 * @deprecated This API is for technology preview only. 1267 */ 1268 Builder& addAttribute(const UnicodeString &key, Operand&& value, UErrorCode& status); 1269 /** 1270 * Constructs a new immutable `Expression` using the operand and operator that 1271 * were previously set. If neither `setOperand()` nor `setOperator()` was 1272 * previously called, or if `setOperand()` was called with the null operand 1273 * and `setOperator()` was never called, then `status` is set to 1274 * U_INVALID_STATE_ERROR. 1275 * 1276 * The builder object (`this`) can still be used after calling `build()`. 1277 * The `build()` method is non-const for internal implementation reasons, 1278 * but is observably const. 1279 1280 * @param status Input/output error code. 1281 * @return The new Expression. 1282 * 1283 * @internal ICU 75 technology preview 1284 * @deprecated This API is for technology preview only. 1285 */ 1286 Expression build(UErrorCode& status); 1287 /** 1288 * Default constructor. 1289 * Returns a Builder with no operator or operand set. 1290 * 1291 * @param status Input/output error code. 1292 * 1293 * @internal ICU 75 technology preview 1294 * @deprecated This API is for technology preview only. 1295 */ 1296 Builder(UErrorCode& status); 1297 /** 1298 * Destructor. 1299 * 1300 * @internal ICU 75 technology preview 1301 * @deprecated This API is for technology preview only. 1302 */ 1303 virtual ~Builder(); 1304 Builder(const Builder&) = delete; 1305 Builder& operator=(const Builder&) = delete; 1306 Builder(Builder&&) = delete; 1307 Builder& operator=(Builder&&) = delete; 1308 }; // class Expression::Builder 1309 /** 1310 * Non-member swap function. 1311 * @param e1 will get e2's contents 1312 * @param e2 will get e1's contents 1313 * 1314 * @internal ICU 75 technology preview 1315 * @deprecated This API is for technology preview only. 1316 */ 1317 U_I18N_API friend inline void swap(Expression& e1, Expression& e2) noexcept { 1318 using std::swap; 1319 1320 swap(e1.rator, e2.rator); 1321 swap(e1.rand, e2.rand); 1322 swap(e1.attributes, e2.attributes); 1323 } 1324 /** 1325 * Copy constructor. 1326 * 1327 * @internal ICU 75 technology preview 1328 * @deprecated This API is for technology preview only. 1329 */ 1330 U_I18N_API Expression(const Expression& other); 1331 /** 1332 * Assignment operator. 1333 * 1334 * @internal ICU 75 technology preview 1335 * @deprecated This API is for technology preview only. 1336 */ 1337 U_I18N_API Expression& operator=(Expression) noexcept; 1338 /** 1339 * Default constructor. 1340 * Puts the Expression into a valid but undefined state. 1341 * 1342 * @internal ICU 75 technology preview 1343 * @deprecated This API is for technology preview only. 1344 */ 1345 U_I18N_API Expression(); 1346 /** 1347 * Destructor. 1348 * 1349 * @internal ICU 75 technology preview 1350 * @deprecated This API is for technology preview only. 1351 */ 1352 U_I18N_API virtual ~Expression(); 1353 private: 1354 friend class message2::Serializer; 1355 1356 /* 1357 Internally, an expression is represented as the application of an optional operator to an operand. 1358 The operand is always present; for function calls with no operand, it's represented 1359 as an operand for which `isNull()` is true. 1360 1361 Operator | Operand 1362 -------------------------------- 1363 { |42| :fun opt=value } => (FunctionName=fun, | Literal(quoted=true, contents="42") 1364 options={opt: value}) 1365 { abcd } => null | Literal(quoted=false, contents="abcd") 1366 { : fun opt=value } => (FunctionName=fun, 1367 options={opt: value}) | NullOperand() 1368 */ 1369 1370 Expression(const Operator &rAtor, const Operand &rAnd, const OptionMap& attrs) : rator(rAtor), rand(rAnd), attributes(attrs) {} 1371 Expression(const Operand &rAnd, const OptionMap& attrs) : rator(std::nullopt), rand(Operand(rAnd)), attributes(attrs) {} 1372 Expression(const Operator &rAtor, const OptionMap& attrs) : rator(rAtor), rand(), attributes(attrs) {} 1373 /* const */ std::optional<Operator> rator; 1374 /* const */ Operand rand; 1375 /* const */ OptionMap attributes; 1376 const OptionMap& getAttributesInternal() const { return attributes; } 1377 }; // class Expression 1378 1379 class Pattern; 1380 1381 // Despite the comments, `PatternPart` is internal-only 1382 /** 1383 * A `PatternPart` is a single element (text or expression) in a `Pattern`. 1384 * It corresponds to the `body` field of the `Pattern` interface 1385 * defined in https://github.com/unicode-org/message-format-wg/blob/main/spec/data-model.md#patterns 1386 * 1387 * `PatternPart` is immutable, copyable and movable. 1388 * 1389 * @internal ICU 75 technology preview 1390 * @deprecated This API is for technology preview only. 1391 */ 1392 class U_I18N_API_CLASS PatternPart : public UObject { 1393 public: 1394 /** 1395 * Checks if the part is a text part. 1396 * 1397 * @return True if and only if this is a text part. 1398 * 1399 * @internal ICU 75 technology preview 1400 * @deprecated This API is for technology preview only. 1401 */ 1402 U_I18N_API UBool isText() const { return std::holds_alternative<UnicodeString>(piece); } 1403 /** 1404 * Checks if the part is a markup part. 1405 * 1406 * @return True if and only if this is a markup part. 1407 * 1408 * @internal ICU 75 technology preview 1409 * @deprecated This API is for technology preview only. 1410 */ 1411 U_I18N_API UBool isMarkup() const { return std::holds_alternative<Markup>(piece); } 1412 /** 1413 * Checks if the part is an expression part. 1414 * 1415 * @return True if and only if this is an expression part. 1416 * 1417 * @internal ICU 75 technology preview 1418 * @deprecated This API is for technology preview only. 1419 */ 1420 U_I18N_API UBool isExpression() const { return std::holds_alternative<Expression>(piece); } 1421 /** 1422 * Accesses the expression of the part. 1423 * Precondition: isExpression() 1424 * 1425 * @return A reference to the part's underlying expression. 1426 * 1427 * @internal ICU 75 technology preview 1428 * @deprecated This API is for technology preview only. 1429 */ 1430 U_I18N_API const Expression& contents() const; 1431 /** 1432 * Accesses the expression of the part. 1433 * Precondition: isMarkup() 1434 * 1435 * @return A reference to the part's underlying expression. 1436 * 1437 * @internal ICU 75 technology preview 1438 * @deprecated This API is for technology preview only. 1439 */ 1440 U_I18N_API const Markup& asMarkup() const; 1441 /** 1442 * Accesses the text contents of the part. 1443 * Precondition: isText() 1444 * 1445 * @return A reference to a string representing the part's text.. 1446 * 1447 * @internal ICU 75 technology preview 1448 * @deprecated This API is for technology preview only. 1449 */ 1450 U_I18N_API const UnicodeString& asText() const; 1451 /** 1452 * Non-member swap function. 1453 * @param p1 will get p2's contents 1454 * @param p2 will get p1's contents 1455 * 1456 * @internal ICU 75 technology preview 1457 * @deprecated This API is for technology preview only. 1458 */ 1459 U_I18N_API friend inline void swap(PatternPart& p1, PatternPart& p2) noexcept { 1460 using std::swap; 1461 1462 swap(p1.piece, p2.piece); 1463 } 1464 /** 1465 * Copy constructor. 1466 * 1467 * @internal ICU 75 technology preview 1468 * @deprecated This API is for technology preview only. 1469 */ 1470 U_I18N_API PatternPart(const PatternPart& other); 1471 /** 1472 * Assignment operator. 1473 * 1474 * @internal ICU 75 technology preview 1475 * @deprecated This API is for technology preview only. 1476 */ 1477 U_I18N_API PatternPart& operator=(PatternPart) noexcept; 1478 /** 1479 * Destructor. 1480 * 1481 * @internal ICU 75 technology preview 1482 * @deprecated This API is for technology preview only. 1483 */ 1484 U_I18N_API virtual ~PatternPart(); 1485 /** 1486 * Text part constructor. Returns a text pattern part 1487 * with text `t`. 1488 * 1489 * @param t A text string. 1490 * 1491 * @internal ICU 75 technology preview 1492 * @deprecated This API is for technology preview only. 1493 */ 1494 U_I18N_API explicit PatternPart(const UnicodeString& t) : piece(t) {} 1495 /** 1496 * Expression part constructor. Returns an Expression pattern 1497 * part with expression `e`. 1498 * 1499 * @param e An Expression. 1500 * 1501 * @internal ICU 75 technology preview 1502 * @deprecated This API is for technology preview only. 1503 */ 1504 U_I18N_API explicit PatternPart(Expression&& e) : piece(e) {} 1505 /** 1506 * Markup part constructor. Returns a Markup pattern 1507 * part with markup `m` 1508 * 1509 * @param m A Markup. 1510 * 1511 * @internal ICU 75 technology preview 1512 * @deprecated This API is for technology preview only. 1513 */ 1514 U_I18N_API explicit PatternPart(Markup&& m) : piece(m) {} 1515 /** 1516 * Default constructor. 1517 * Puts the PatternPart into a valid but undefined state. 1518 * 1519 * @internal ICU 75 technology preview 1520 * @deprecated This API is for technology preview only. 1521 */ 1522 U_I18N_API PatternPart() = default; 1523 private: 1524 friend class Pattern; 1525 1526 std::variant<UnicodeString, Expression, Markup> piece; 1527 }; // class PatternPart 1528 1529 /** 1530 * A `Pattern` is a sequence of formattable parts. 1531 * It corresponds to the `Pattern` interface 1532 * defined in https://github.com/unicode-org/message-format-wg/blob/main/spec/data-model.md#patterns 1533 * 1534 * `Pattern` is immutable, copyable and movable. 1535 * 1536 * @internal ICU 75 technology preview 1537 * @deprecated This API is for technology preview only. 1538 */ 1539 class U_I18N_API_CLASS Pattern : public UObject { 1540 private: 1541 friend class PatternPart; 1542 1543 public: 1544 #ifndef U_IN_DOXYGEN 1545 struct U_I18N_API Iterator; 1546 #endif 1547 /** 1548 * Returns the parts of this pattern 1549 * 1550 * @return A forward iterator of variants. Each element is either a string (text part) 1551 * or an expression part. 1552 * 1553 * @internal ICU 75 technology preview 1554 * @deprecated This API is for technology preview only. 1555 */ 1556 U_I18N_API Iterator begin() const { 1557 return Iterator(this, 0); 1558 } 1559 /** 1560 * Returns a special value to mark the end of iteration 1561 * 1562 * @return A forward iterator of variants. This should only be used for comparisons 1563 * against an iterator returned by incrementing begin(). 1564 * 1565 * @internal ICU 75 technology preview 1566 * @deprecated This API is for technology preview only. 1567 */ 1568 U_I18N_API Iterator end() const { 1569 return Iterator(this, len); 1570 } 1571 /** 1572 * The mutable `Pattern::Builder` class allows the pattern to be 1573 * constructed one part at a time. 1574 * 1575 * Builder is not copyable or movable. 1576 * 1577 * @internal ICU 75 technology preview 1578 * @deprecated This API is for technology preview only. 1579 */ 1580 class U_I18N_API Builder : public UMemory { 1581 private: 1582 friend class Pattern; 1583 1584 UVector* parts; // Not a LocalPointer for the same reason as in `SelectorKeys::Builder` 1585 1586 public: 1587 /** 1588 * Adds a single expression part to the pattern. 1589 * 1590 * @param part The part to be added (passed by move) 1591 * @param status Input/output error code. 1592 * @return A reference to the builder. 1593 * 1594 * @internal ICU 75 technology preview 1595 * @deprecated This API is for technology preview only. 1596 */ 1597 Builder& add(Expression&& part, UErrorCode& status) noexcept; 1598 /** 1599 * Adds a single markup part to the pattern. 1600 * 1601 * @param part The part to be added (passed by move) 1602 * @param status Input/output error code. 1603 * @return A reference to the builder. 1604 * 1605 * @internal ICU 75 technology preview 1606 * @deprecated This API is for technology preview only. 1607 */ 1608 Builder& add(Markup&& part, UErrorCode& status) noexcept; 1609 /** 1610 * Adds a single text part to the pattern. Copies `part`. 1611 * 1612 * @param part The part to be added (passed by move) 1613 * @param status Input/output error code. 1614 * @return A reference to the builder. 1615 * 1616 * @internal ICU 75 technology preview 1617 * @deprecated This API is for technology preview only. 1618 */ 1619 Builder& add(UnicodeString&& part, UErrorCode& status) noexcept; 1620 /** 1621 * Constructs a new immutable `Pattern` using the list of parts 1622 * set with previous `add()` calls. 1623 * 1624 * The builder object (`this`) can still be used after calling `build()`. 1625 * 1626 * @param status Input/output error code. 1627 * @return The pattern object 1628 * 1629 * @internal ICU 75 technology preview 1630 * @deprecated This API is for technology preview only. 1631 */ 1632 Pattern build(UErrorCode& status) const noexcept; 1633 /** 1634 * Default constructor. 1635 * Returns a Builder with an empty sequence of PatternParts. 1636 * 1637 * @param status Input/output error code 1638 * 1639 * @internal ICU 75 technology preview 1640 * @deprecated This API is for technology preview only. 1641 */ 1642 Builder(UErrorCode& status); 1643 /** 1644 * Destructor. 1645 * 1646 * @internal ICU 75 technology preview 1647 * @deprecated This API is for technology preview only. 1648 */ 1649 virtual ~Builder(); 1650 Builder(const Builder&) = delete; 1651 Builder& operator=(const Builder&) = delete; 1652 Builder(Builder&&) = delete; 1653 Builder& operator=(Builder&&) = delete; 1654 }; // class Pattern::Builder 1655 1656 /** 1657 * Default constructor. 1658 * Puts the Pattern into a valid but undefined state. 1659 * 1660 * @internal ICU 75 technology preview 1661 * @deprecated This API is for technology preview only. 1662 */ 1663 U_I18N_API Pattern() : parts(LocalArray<PatternPart>()) {} 1664 /** 1665 * Non-member swap function. 1666 * @param p1 will get p2's contents 1667 * @param p2 will get p1's contents 1668 * 1669 * @internal ICU 75 technology preview 1670 * @deprecated This API is for technology preview only. 1671 */ 1672 U_I18N_API friend inline void swap(Pattern& p1, Pattern& p2) noexcept { 1673 using std::swap; 1674 1675 swap(p1.bogus, p2.bogus); 1676 swap(p1.len, p2.len); 1677 swap(p1.parts, p2.parts); 1678 } 1679 /** 1680 * Copy constructor. 1681 * 1682 * @internal ICU 75 technology preview 1683 * @deprecated This API is for technology preview only. 1684 */ 1685 U_I18N_API Pattern(const Pattern& other); 1686 /** 1687 * Assignment operator 1688 * 1689 * @internal ICU 75 technology preview 1690 * @deprecated This API is for technology preview only. 1691 */ 1692 U_I18N_API Pattern& operator=(Pattern) noexcept; 1693 /** 1694 * Destructor. 1695 * 1696 * @internal ICU 75 technology preview 1697 * @deprecated This API is for technology preview only. 1698 */ 1699 U_I18N_API virtual ~Pattern(); 1700 1701 /** 1702 * The `Pattern::Iterator` class provides an iterator over the formattable 1703 * parts of a pattern. 1704 * 1705 * `Pattern::Iterator` is mutable and is not copyable or movable. 1706 * 1707 * @internal ICU 75 technology preview 1708 * @deprecated This API is for technology preview only. 1709 */ 1710 struct U_I18N_API Iterator { 1711 private: 1712 using iterator_category = std::forward_iterator_tag; 1713 using difference_type = std::ptrdiff_t; 1714 using value_type = std::variant<UnicodeString, Expression, Markup>; 1715 using pointer = value_type*; 1716 using reference = const value_type&; 1717 1718 friend class Pattern; 1719 Iterator(const Pattern* p, int32_t i) : pos(i), pat(p) {} 1720 friend bool operator== (const Iterator& a, const Iterator& b) { return (a.pat == b.pat && a.pos == b.pos); } 1721 1722 int32_t pos; 1723 const Pattern* pat; 1724 1725 public: 1726 /** 1727 * Dereference operator (gets the element at the current iterator position) 1728 * 1729 * @internal ICU 75 technology preview 1730 * @deprecated This API is for technology preview only. 1731 */ 1732 reference operator*() const { 1733 const PatternPart& part = pat->parts[pos]; 1734 return patternContents(part); 1735 } 1736 /** 1737 * Increment operator (advances to the next iterator position) 1738 * 1739 * @internal ICU 75 technology preview 1740 * @deprecated This API is for technology preview only. 1741 */ 1742 Iterator operator++() { pos++; return *this; } 1743 /** 1744 * Inequality comparison operator (used for comparing an iterator to the result of end()) 1745 * 1746 * @internal ICU 75 technology preview 1747 * @deprecated This API is for technology preview only. 1748 */ 1749 friend bool operator!= (const Iterator& a, const Iterator& b) { return !(a == b); } 1750 }; // struct Iterator 1751 1752 private: 1753 friend class Builder; 1754 friend class message2::MessageFormatter; 1755 friend class message2::Serializer; 1756 1757 // Set to true if a copy constructor fails; 1758 // needed in order to distinguish an uninitialized 1759 // Pattern from a 0-length pattern 1760 bool bogus = false; 1761 1762 // Possibly-empty array of parts 1763 int32_t len = 0; 1764 LocalArray<PatternPart> parts; 1765 1766 Pattern(const UVector& parts, UErrorCode& status); 1767 // Helper 1768 static void initParts(Pattern&, const Pattern&); 1769 1770 /** 1771 * Returns the size. 1772 * 1773 * @return The number of parts in the pattern. 1774 * 1775 * @internal ICU 75 technology preview 1776 * @deprecated This API is for technology preview only. 1777 */ 1778 int32_t numParts() const; 1779 /** 1780 * Returns the `i`th part in the pattern. 1781 * Precondition: i < numParts() 1782 * 1783 * @param i Index of the part being accessed. 1784 * @return A reference to the part at index `i`. 1785 * 1786 * @internal ICU 75 technology preview 1787 * @deprecated This API is for technology preview only. 1788 */ 1789 const PatternPart& getPart(int32_t i) const; 1790 1791 // Gets around not being able to declare Pattern::Iterator as a friend 1792 // in PatternPart 1793 static const std::variant<UnicodeString, Expression, Markup>& 1794 patternContents(const PatternPart& p) { return p.piece; } 1795 }; // class Pattern 1796 1797 /** 1798 * A `Variant` pairs a list of keys with a pattern 1799 * It corresponds to the `Variant` interface 1800 * defined in https://github.com/unicode-org/message-format-wg/tree/main/spec/data-model 1801 * 1802 * `Variant` is immutable, copyable and movable. 1803 * 1804 * @internal ICU 75 technology preview 1805 * @deprecated This API is for technology preview only. 1806 */ 1807 class U_I18N_API Variant : public UObject { 1808 public: 1809 /** 1810 * Accesses the pattern of the variant. 1811 * 1812 * @return A reference to the pattern. 1813 * 1814 * @internal ICU 75 technology preview 1815 * @deprecated This API is for technology preview only. 1816 */ 1817 const Pattern& getPattern() const { return p; } 1818 /** 1819 * Accesses the keys of the variant. 1820 * 1821 * @return A reference to the keys. 1822 * 1823 * @internal ICU 75 technology preview 1824 * @deprecated This API is for technology preview only. 1825 */ 1826 const SelectorKeys& getKeys() const { return k; } 1827 /** 1828 * Constructor. Returns a variant that formats to `pattern` 1829 * when `keys` match the selector expressions in the enclosing 1830 * `match` construct. 1831 * 1832 * @param keys A reference to a `SelectorKeys`. 1833 * @param pattern A pattern (passed by move) 1834 * 1835 * @internal ICU 75 technology preview 1836 * @deprecated This API is for technology preview only. 1837 */ 1838 Variant(const SelectorKeys& keys, Pattern&& pattern) : k(keys), p(std::move(pattern)) {} 1839 /** 1840 * Non-member swap function. 1841 * @param v1 will get v2's contents 1842 * @param v2 will get v1's contents 1843 * 1844 * @internal ICU 75 technology preview 1845 * @deprecated This API is for technology preview only. 1846 */ 1847 friend inline void swap(Variant& v1, Variant& v2) noexcept { 1848 using std::swap; 1849 1850 swap(v1.k, v2.k); 1851 swap(v1.p, v2.p); 1852 } 1853 /** 1854 * Assignment operator 1855 * 1856 * @internal ICU 75 technology preview 1857 * @deprecated This API is for technology preview only. 1858 */ 1859 Variant& operator=(Variant other) noexcept; 1860 /** 1861 * Default constructor. 1862 * Returns a Variant in a valid but undefined state. 1863 * 1864 * @internal ICU 75 technology preview 1865 * @deprecated This API is for technology preview only. 1866 */ 1867 Variant() = default; 1868 /** 1869 * Copy constructor. 1870 * 1871 * @internal ICU 75 technology preview 1872 * @deprecated This API is for technology preview only. 1873 */ 1874 Variant(const Variant&); 1875 /** 1876 * Destructor. 1877 * 1878 * @internal ICU 75 technology preview 1879 * @deprecated This API is for technology preview only. 1880 */ 1881 virtual ~Variant(); 1882 private: 1883 /* const */ SelectorKeys k; 1884 /* const */ Pattern p; 1885 }; // class Variant 1886 1887 /** 1888 * A `Binding` pairs a variable name with an expression. 1889 * It corresponds to the `Declaration` interface 1890 * defined in https://github.com/unicode-org/message-format-wg/blob/main/spec/data-model.md#messages 1891 * 1892 * `Binding` is immutable and copyable. It is not movable. 1893 * 1894 * @internal ICU 75 technology preview 1895 * @deprecated This API is for technology preview only. 1896 */ 1897 class U_I18N_API Binding : public UObject { 1898 public: 1899 /** 1900 * Accesses the right-hand side of a binding. 1901 * 1902 * @return A reference to the expression. 1903 * 1904 * @internal ICU 75 technology preview 1905 * @deprecated This API is for technology preview only. 1906 */ 1907 const Expression& getValue() const; 1908 /** 1909 * Accesses the left-hand side of the binding. 1910 * 1911 * @return A reference to the variable name. 1912 * 1913 * @internal ICU 75 technology preview 1914 * @deprecated This API is for technology preview only. 1915 */ 1916 const VariableName& getVariable() const { return var; } 1917 /** 1918 * Constructor for input binding. 1919 * 1920 * @param variableName The variable name (left-hand side) of the binding. Passed by move. 1921 * @param rhs The right-hand side of the input binding. Passed by move. 1922 * `rhs` must have an operand that is a variable reference to `variableName`. 1923 * If `rhs` has an operator, it must be a function call. 1924 * If either of these properties is violated, `errorCode` is set to 1925 * U_INVALID_STATE_ERROR. 1926 * @param errorCode Input/output error code 1927 * 1928 * @internal ICU 75 technology preview 1929 * @deprecated This API is for technology preview only. 1930 */ 1931 static Binding input(UnicodeString&& variableName, Expression&& rhs, UErrorCode& errorCode); 1932 /** 1933 * Returns true if and only if this binding represents a local declaration. 1934 * Otherwise, it's an input declaration. 1935 * 1936 * @return True if this binding represents a variable and expression; 1937 * false if it represents a variable plus an annotation. 1938 * @internal ICU 78 technology preview 1939 * @deprecated This API is for technology preview only. 1940 */ 1941 UBool isLocal() const { return local; } 1942 /** 1943 * Constructor. 1944 * 1945 * @param v A variable name. 1946 * @param e An expression. 1947 * 1948 * @internal ICU 75 technology preview 1949 * @deprecated This API is for technology preview only. 1950 */ 1951 Binding(const VariableName& v, Expression&& e) : var(v), expr(std::move(e)), local(true), annotation(nullptr) {} 1952 /** 1953 * Non-member swap function. 1954 * @param b1 will get b2's contents 1955 * @param b2 will get b1's contents 1956 * 1957 * @internal ICU 75 technology preview 1958 * @deprecated This API is for technology preview only. 1959 */ 1960 friend inline void swap(Binding& b1, Binding& b2) noexcept { 1961 using std::swap; 1962 1963 swap(b1.var, b2.var); 1964 swap(b1.expr, b2.expr); 1965 swap(b1.local, b2.local); 1966 b1.updateAnnotation(); 1967 b2.updateAnnotation(); 1968 } 1969 /** 1970 * Copy constructor. 1971 * 1972 * @internal ICU 75 technology preview 1973 * @deprecated This API is for technology preview only. 1974 */ 1975 Binding(const Binding& other); 1976 /** 1977 * Copy assignment operator 1978 * 1979 * @internal ICU 75 technology preview 1980 * @deprecated This API is for technology preview only. 1981 */ 1982 Binding& operator=(Binding) noexcept; 1983 /** 1984 * Default constructor. 1985 * Puts the Binding into a valid but undefined state. 1986 * 1987 * @internal ICU 75 technology preview 1988 * @deprecated This API is for technology preview only. 1989 */ 1990 Binding() : local(true) {} 1991 /** 1992 * Destructor. 1993 * 1994 * @internal ICU 75 technology preview 1995 * @deprecated This API is for technology preview only. 1996 */ 1997 virtual ~Binding(); 1998 private: 1999 friend class message2::Checker; 2000 friend class message2::MessageFormatter; 2001 friend class message2::Parser; 2002 friend class message2::Serializer; 2003 2004 /* const */ VariableName var; 2005 /* const */ Expression expr; 2006 /* const */ bool local; 2007 2008 // The following field is always nullptr for a local 2009 // declaration, and possibly nullptr for an .input declaration 2010 // If non-null, the referent is a member of `expr` so 2011 // its lifetime is the same as the lifetime of the enclosing Binding 2012 // (as long as there's no mutation) 2013 const Operator* annotation = nullptr; 2014 2015 const OptionMap& getOptionsInternal() const; 2016 2017 bool hasAnnotation() const { return !local && (annotation != nullptr); } 2018 void updateAnnotation(); 2019 }; // class Binding 2020 2021 // Internal only 2022 2023 #ifndef U_IN_DOXYGEN 2024 class U_I18N_API_CLASS Matcher : public UObject { 2025 public: 2026 U_I18N_API Matcher& operator=(Matcher); 2027 U_I18N_API Matcher(const Matcher&); 2028 /** 2029 * Non-member swap function. 2030 * @param m1 will get m2's contents 2031 * @param m2 will get m1's contents 2032 * 2033 * @internal ICU 75 technology preview 2034 * @deprecated This API is for technology preview only. 2035 */ 2036 U_I18N_API friend inline void swap(Matcher& m1, Matcher& m2) noexcept { 2037 using std::swap; 2038 2039 if (m1.bogus) { 2040 m2.bogus = true; 2041 return; 2042 } 2043 if (m2.bogus) { 2044 m1.bogus = true; 2045 return; 2046 } 2047 swap(m1.selectors, m2.selectors); 2048 swap(m1.numSelectors, m2.numSelectors); 2049 swap(m1.variants, m2.variants); 2050 swap(m1.numVariants, m2.numVariants); 2051 } 2052 U_I18N_API virtual ~Matcher(); 2053 private: 2054 2055 friend class MFDataModel; 2056 2057 Matcher(VariableName* ss, int32_t ns, Variant* vs, int32_t nv); 2058 Matcher() {} 2059 2060 // A Matcher may have numSelectors=0 and numVariants=0 2061 // (this is a data model error, but it's representable). 2062 // So we have to keep a separate flag to track failed copies. 2063 bool bogus = false; 2064 2065 // The variables that are being matched on. 2066 LocalArray<VariableName> selectors; 2067 // The number of selectors 2068 int32_t numSelectors = 0; 2069 // The list of `when` clauses (case arms). 2070 LocalArray<Variant> variants; 2071 // The number of variants 2072 int32_t numVariants = 0; 2073 }; // class Matcher 2074 #endif 2075 2076 // ----------------------------------------------------------------------- 2077 // Public MFDataModel class 2078 2079 /** 2080 * 2081 * The `MFDataModel` class describes a parsed representation of the text of a message. 2082 * This representation is public as higher-level APIs for messages will need to know its public 2083 * interface: for example, to re-instantiate a parsed message with different values for imported 2084 variables. 2085 * 2086 * The MFDataModel API implements <a target="github" 2087 href="https://github.com/unicode-org/message-format-wg/blob/main/spec/data-model.md">the 2088 * specification of the abstract syntax (data model representation)</a> for MessageFormat. 2089 * 2090 * `MFDataModel` is immutable, copyable and movable. 2091 * 2092 * @internal ICU 75 technology preview 2093 * @deprecated This API is for technology preview only. 2094 */ 2095 class U_I18N_API_CLASS MFDataModel : public UMemory { 2096 /* 2097 Classes that represent nodes in the data model are nested inside the 2098 `MFDataModel` class. 2099 2100 Classes such as `Expression`, `Pattern` and `VariantMap` are immutable and 2101 are constructed using the builder pattern. 2102 2103 Most classes representing nodes have copy constructors. This is because builders 2104 contain immutable data that must be copied when calling `build()`, since the builder 2105 could go out of scope before the immutable result of the builder does. Copying is 2106 also necessary to prevent unexpected mutation if intermediate builders are saved 2107 and mutated again after calling `build()`. 2108 2109 The copy constructors perform a deep copy, for example by copying the entire 2110 list of options for an `Operator` (and copying the entire underlying vector.) 2111 Some internal fields should be `const`, but are declared as non-`const` to make 2112 the copy constructor simpler to implement. (These are noted throughout.) In 2113 other words, those fields are `const` except during the execution of a copy 2114 constructor. 2115 2116 On the other hand, intermediate `Builder` methods that return a `Builder&` 2117 mutate the state of the builder, so in code like: 2118 2119 Expression::Builder& exprBuilder = Expression::builder()-> setOperand(foo); 2120 Expression::Builder& exprBuilder2 = exprBuilder.setOperator(bar); 2121 2122 the call to `setOperator()` would mutate `exprBuilder`, since `exprBuilder` 2123 and `exprBuilder2` are references to the same object. 2124 2125 An alternate choice would be to make `build()` destructive, so that copying would 2126 be unnecessary. Or, both copying and moving variants of `build()` could be 2127 provided. Copying variants of the intermediate `Builder` methods could be 2128 provided as well, if this proved useful. 2129 */ 2130 public: 2131 /** 2132 * Accesses the local variable declarations for this data model. 2133 * 2134 * @return A vector of bindings for local variables. 2135 * 2136 * @internal ICU 75 technology preview 2137 * @deprecated This API is for technology preview only. 2138 */ 2139 U_I18N_API std::vector<Binding> getLocalVariables() const { 2140 std::vector<Binding> result; 2141 if (!bogus) { 2142 return toStdVector<Binding>(bindings.getAlias(), bindingsLen); 2143 } 2144 return {}; 2145 } 2146 /** 2147 * Accesses the selectors. Returns an empty vector if this is a pattern message. 2148 * 2149 * @return A vector of selectors. 2150 * 2151 * @internal ICU 75 technology preview 2152 * @deprecated This API is for technology preview only. 2153 */ 2154 U_I18N_API std::vector<VariableName> getSelectors() const { 2155 if (std::holds_alternative<Pattern>(body)) { 2156 return {}; 2157 } 2158 const Matcher* match = std::get_if<Matcher>(&body); 2159 // match must be non-null, given the previous check 2160 return toStdVector<VariableName>(match->selectors.getAlias(), match->numSelectors); 2161 } 2162 /** 2163 * Accesses the variants. Returns an empty vector if this is a pattern message. 2164 * 2165 * @return A vector of variants. 2166 * 2167 * @internal ICU 75 technology preview 2168 * @deprecated This API is for technology preview only. 2169 */ 2170 U_I18N_API std::vector<Variant> getVariants() const { 2171 // Return empty vector if no variants 2172 if (std::holds_alternative<Pattern>(body)) { 2173 return {}; 2174 } 2175 const Matcher* match = std::get_if<Matcher>(&body); 2176 // match must be non-null, given the previous check 2177 return toStdVector<Variant>(match->variants.getAlias(), match->numVariants); 2178 return {}; 2179 } 2180 /** 2181 * Accesses the pattern (in a message without selectors). 2182 * Returns a reference to an empty pattern if the message has selectors. 2183 * 2184 * @return A reference to the pattern. 2185 * 2186 * @internal ICU 75 technology preview 2187 * @deprecated This API is for technology preview only. 2188 */ 2189 U_I18N_API const Pattern& getPattern() const; 2190 /** 2191 * The mutable `MFDataModel::Builder` class allows the data model to be 2192 * constructed incrementally. 2193 * 2194 * @internal ICU 75 technology preview 2195 * @deprecated This API is for technology preview only. 2196 */ 2197 class U_I18N_API Builder; 2198 /** 2199 * Default constructor. 2200 * Puts the MFDataModel into a valid but undefined state. 2201 * 2202 * @internal ICU 75 technology preview 2203 * @deprecated This API is for technology preview only. 2204 */ 2205 U_I18N_API MFDataModel(); 2206 /** 2207 * Non-member swap function. 2208 * @param m1 will get m2's contents 2209 * @param m2 will get m1's contents 2210 * 2211 * @internal ICU 75 technology preview 2212 * @deprecated This API is for technology preview only. 2213 */ 2214 U_I18N_API friend inline void swap(MFDataModel& m1, MFDataModel& m2) noexcept { 2215 using std::swap; 2216 2217 if (m1.bogus) { 2218 m2.bogus = true; 2219 return; 2220 } 2221 if (m2.bogus) { 2222 m1.bogus = true; 2223 return; 2224 } 2225 swap(m1.body, m2.body); 2226 swap(m1.bindings, m2.bindings); 2227 swap(m1.bindingsLen, m2.bindingsLen); 2228 } 2229 /** 2230 * Assignment operator 2231 * 2232 * @internal ICU 75 technology preview 2233 * @deprecated This API is for technology preview only. 2234 */ 2235 U_I18N_API MFDataModel& operator=(MFDataModel) noexcept; 2236 /** 2237 * Copy constructor. 2238 * 2239 * @internal ICU 75 technology preview 2240 * @deprecated This API is for technology preview only. 2241 */ 2242 U_I18N_API MFDataModel(const MFDataModel& other); 2243 /** 2244 * Destructor. 2245 * 2246 * @internal ICU 75 technology preview 2247 * @deprecated This API is for technology preview only. 2248 */ 2249 U_I18N_API virtual ~MFDataModel(); 2250 2251 /** 2252 * The mutable `MFDataModel::Builder` class allows the data model to be 2253 * constructed incrementally. Builder is not copyable or movable. 2254 * 2255 * @internal ICU 75 technology preview 2256 * @deprecated This API is for technology preview only. 2257 */ 2258 class U_I18N_API Builder : public UMemory { 2259 private: 2260 friend class MFDataModel; 2261 2262 void checkDuplicate(const VariableName&, UErrorCode&) const; 2263 void buildSelectorsMessage(UErrorCode&); 2264 bool hasPattern = true; 2265 bool hasSelectors = false; 2266 Pattern pattern; 2267 // The following members are not LocalPointers for the same reason as in SelectorKeys::Builder 2268 UVector* selectors = nullptr; 2269 UVector* variants = nullptr; 2270 UVector* bindings = nullptr; 2271 public: 2272 /** 2273 * Adds a binding, There must not already be a binding 2274 * with the same name. 2275 * 2276 * @param b The binding. Passed by move. 2277 * @param status Input/output error code. Set to U_DUPLICATE_DECLARATION_ERROR 2278 * if `addBinding()` was previously called with a binding 2279 * with the same variable name as `b`. 2280 * 2281 * @internal ICU 75 technology preview 2282 * @deprecated This API is for technology preview only. 2283 */ 2284 Builder& addBinding(Binding&& b, UErrorCode& status); 2285 /** 2286 * Adds a selector variable. 2287 * If a pattern was previously set, clears the pattern. 2288 * 2289 * @param selector Variable to add as a selector. Passed by move. 2290 * @param errorCode Input/output error code 2291 * @return A reference to the builder. 2292 * 2293 * @internal ICU 75 technology preview 2294 * @deprecated This API is for technology preview only. 2295 */ 2296 Builder& addSelector(VariableName&& selector, UErrorCode& errorCode); 2297 /** 2298 * Adds a single variant. 2299 * If a pattern was previously set using `setPattern()`, clears the pattern. 2300 * 2301 * @param keys Keys for the variant. Passed by move. 2302 * @param pattern Pattern for the variant. Passed by move. 2303 * @param errorCode Input/output error code 2304 * @return A reference to the builder. 2305 * 2306 * @internal ICU 75 technology preview 2307 * @deprecated This API is for technology preview only. 2308 */ 2309 Builder& addVariant(SelectorKeys&& keys, Pattern&& pattern, UErrorCode& errorCode) noexcept; 2310 /** 2311 * Sets the body of the message as a pattern. 2312 * If selectors and/or variants were previously set, clears them. 2313 * 2314 * @param pattern Pattern to represent the body of the message. 2315 * Passed by move. 2316 * @return A reference to the builder. 2317 * 2318 * @internal ICU 75 technology preview 2319 * @deprecated This API is for technology preview only. 2320 */ 2321 Builder& setPattern(Pattern&& pattern); 2322 /** 2323 * Constructs a new immutable data model. 2324 * If `setPattern()` has not been called and if `addSelector()` and 2325 * `addVariant()` were not each called at least once, 2326 * `status` is set to `U_INVALID_STATE_ERROR`. 2327 * If `addSelector()` was called and `addVariant()` was never called, 2328 * or vice versa, then `status` is set to U_INVALID_STATE_ERROR. 2329 * Otherwise, either a Pattern or Selectors message is constructed 2330 * based on the pattern that was previously set, or selectors and variants 2331 * that were previously set. 2332 * 2333 * The builder object (`this`) can still be used after calling `build()`. 2334 * 2335 * @param status Input/output error code. 2336 * @return The new MFDataModel 2337 * 2338 * @internal ICU 75 technology preview 2339 * @deprecated This API is for technology preview only. 2340 */ 2341 MFDataModel build(UErrorCode& status) const noexcept; 2342 /** 2343 * Default constructor. 2344 * Returns a Builder with no pattern or selectors set. 2345 * Either `setPattern()` or both `addSelector()` and 2346 * `addVariant()` must be called before calling `build()` 2347 * on the resulting builder. 2348 * 2349 * @param status Input/output error code. 2350 * 2351 * @internal ICU 75 technology preview 2352 * @deprecated This API is for technology preview only. 2353 */ 2354 Builder(UErrorCode& status); 2355 /** 2356 * Destructor. 2357 * 2358 * @internal ICU 75 technology preview 2359 * @deprecated This API is for technology preview only. 2360 */ 2361 virtual ~Builder(); 2362 Builder(const Builder&) = delete; 2363 Builder& operator=(const Builder&) = delete; 2364 Builder(Builder&&) = delete; 2365 Builder& operator=(Builder&&) = delete; 2366 }; // class Builder 2367 2368 private: 2369 friend class message2::Checker; 2370 friend class message2::MessageFormatter; 2371 friend class message2::Serializer; 2372 2373 Pattern empty; // Provided so that `getPattern()` can return a result 2374 // if called on a selectors message 2375 bool hasPattern() const { return std::holds_alternative<Pattern>(body); } 2376 2377 bool bogus = false; // Set if a copy constructor fails 2378 2379 // A message body is either a matcher (selector list and variant list), 2380 // or a single pattern 2381 std::variant<Matcher, Pattern> body; 2382 2383 // Bindings for local variables 2384 /* const */ LocalArray<Binding> bindings; 2385 int32_t bindingsLen = 0; 2386 2387 const Binding* getLocalVariablesInternal() const; 2388 const VariableName* getSelectorsInternal() const; 2389 const Variant* getVariantsInternal() const; 2390 2391 int32_t numSelectors() const { 2392 const Matcher* matcher = std::get_if<Matcher>(&body); 2393 return (matcher == nullptr ? 0 : matcher->numSelectors); 2394 } 2395 int32_t numVariants() const { 2396 const Matcher* matcher = std::get_if<Matcher>(&body); 2397 return (matcher == nullptr ? 0 : matcher->numVariants); 2398 } 2399 2400 // Helper 2401 void initBindings(const Binding*); 2402 2403 MFDataModel(const Builder& builder, UErrorCode&) noexcept; 2404 }; // class MFDataModel 2405 } // namespace data_model 2406 } // namespace message2 2407 2408 U_NAMESPACE_END 2409 2410 #endif // U_HIDE_DEPRECATED_API 2411 2412 #endif /* #if !UCONFIG_NO_MF2 */ 2413 2414 #endif /* #if !UCONFIG_NO_FORMATTING */ 2415 2416 #endif /* #if !UCONFIG_NO_NORMALIZATION */ 2417 2418 #endif /* U_SHOW_CPLUSPLUS_API */ 2419 2420 #endif // MESSAGEFORMAT_DATA_MODEL_H 2421 2422 // eof