Back to home page

EIC code displayed by LXR

 
 

    


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