ICU 75.1  75.1
messageformat2_data_model.h
1 // © 2024 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
3 
4 #include "unicode/utypes.h"
5 
6 #ifndef MESSAGEFORMAT_DATA_MODEL_H
7 #define MESSAGEFORMAT_DATA_MODEL_H
8 
9 #if U_SHOW_CPLUSPLUS_API
10 
11 #if !UCONFIG_NO_FORMATTING
12 
13 #if !UCONFIG_NO_MF2
14 
15 #include "unicode/localpointer.h"
16 #include "unicode/messageformat2_data_model_names.h"
17 
18 #ifndef U_HIDE_DEPRECATED_API
19 
20 #include <algorithm>
21 #include <cstddef>
22 #include <iterator>
23 #include <optional>
24 #include <variant>
25 #include <vector>
26 
27 U_NAMESPACE_BEGIN
28 
29 class UVector;
30 
31 // Helpers
32 
33 // Note: this _must_ be declared `inline` or else gcc will generate code
34 // for its instantiations, which needs to be avoided because it returns
35 // a std::vector
36 template<typename T>
37 static inline std::vector<T> toStdVector(const T* arr, int32_t len) {
38  std::vector<T> result;
39  for (int32_t i = 0; i < len; i++) {
40  result.push_back(arr[i]);
41  }
42  return result;
43 }
44 
45 #if defined(U_REAL_MSVC)
46 #pragma warning(push)
47 // Ignore warning 4251 as these templates are instantiated later in this file,
48 // after the classes used to instantiate them have been defined.
49 #pragma warning(disable: 4251)
50 #endif
51 
52 namespace message2 {
53  class Checker;
54  class MFDataModel;
55  class MessageFormatter;
56  class Parser;
57  class Serializer;
58 
59 
60  namespace data_model {
61  class Binding;
62  class Literal;
63  class Operator;
64 
76  class U_I18N_API Reserved : public UMemory {
77  public:
86  int32_t numParts() const;
97  const Literal& getPart(int32_t i) const;
98 
108  class U_I18N_API Builder : public UMemory {
109  private:
110  UVector* parts; // Not a LocalPointer for the same reason as in `SelectorKeys::Builder`
111 
112  public:
123  Builder& add(Literal&& part, UErrorCode& status) noexcept;
136  Reserved build(UErrorCode& status) const noexcept;
146  Builder(UErrorCode& status);
153  virtual ~Builder();
154  Builder(const Builder&) = delete;
155  Builder& operator=(const Builder&) = delete;
156  Builder(Builder&&) = delete;
157  Builder& operator=(Builder&&) = delete;
158  }; // class Reserved::Builder
167  friend inline void swap(Reserved& r1, Reserved& r2) noexcept {
168  using std::swap;
169 
170  swap(r1.bogus, r2.bogus);
171  swap(r1.parts, r2.parts);
172  swap(r1.len, r2.len);
173  }
180  Reserved(const Reserved& other);
195  Reserved() { parts = LocalArray<Literal>(); }
202  virtual ~Reserved();
203  private:
204  friend class Builder;
205  friend class Operator;
206 
207  // True if a copy failed; this has to be distinguished
208  // from a valid `Reserved` with empty parts
209  bool bogus = false;
210 
211  // Possibly-empty list of parts
212  // `literal` reserved as a quoted literal; `reserved-char` / `reserved-escape`
213  // strings represented as unquoted literals
214  /* const */ LocalArray<Literal> parts;
215  int32_t len = 0;
216 
217  Reserved(const UVector& parts, UErrorCode& status) noexcept;
218  // Helper
219  static void initLiterals(Reserved&, const Reserved&);
220  };
221 
233  class U_I18N_API Literal : public UObject {
234  public:
252  const UnicodeString& unquoted() const;
262  UBool isQuoted() const { return thisIsQuoted; }
274  Literal(UBool q, const UnicodeString& s) : thisIsQuoted(q), contents(s) {}
281  Literal(const Literal& other) : thisIsQuoted(other.thisIsQuoted), contents(other.contents) {}
290  friend inline void swap(Literal& l1, Literal& l2) noexcept {
291  using std::swap;
292 
293  swap(l1.thisIsQuoted, l2.thisIsQuoted);
294  swap(l1.contents, l2.contents);
295  }
310  Literal() = default;
326  bool operator<(const Literal& other) const;
342  bool operator==(const Literal& other) const;
349  virtual ~Literal();
350 
351  private:
352  friend class Reserved::Builder;
353 
354  /* const */ bool thisIsQuoted = false;
355  /* const */ UnicodeString contents;
356  };
357  } // namespace data_model
358 } // namespace message2
359 
361 // Export an explicit template instantiation of the LocalPointer that is used as a
362 // data member of various MFDataModel classes.
363 // (When building DLLs for Windows this is required.)
364 // (See measunit_impl.h, datefmt.h, collationiterator.h, erarules.h and others
365 // for similar examples.)
366 #if U_PF_WINDOWS <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN
369 #endif
370 #if defined(U_REAL_MSVC)
371 #pragma warning(pop)
372 #endif
374 
375 U_NAMESPACE_END
376 
378 // Export an explicit template instantiation of the std::variants and std::optionals
379 // that are used as a data member of various MFDataModel classes.
380 // (When building DLLs for Windows this is required.)
381 // (See measunit_impl.h, datefmt.h, collationiterator.h, erarules.h and others
382 // for similar examples.)
383 #if U_PF_WINDOWS <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN
384 #if defined(U_REAL_MSVC) && defined(_MSVC_STL_VERSION)
385 struct U_I18N_API std::_Nontrivial_dummy_type;
386 template class U_I18N_API std::_Variant_storage_<false, icu::UnicodeString, icu::message2::data_model::Literal>;
387 #endif
388 template class U_I18N_API std::variant<icu::UnicodeString, icu::message2::data_model::Literal>;
389 template class U_I18N_API std::optional<std::variant<icu::UnicodeString, icu::message2::data_model::Literal>>;
390 template class U_I18N_API std::optional<icu::message2::data_model::Literal>;
391 #endif
393 
394 U_NAMESPACE_BEGIN
395 
396 namespace message2 {
397  namespace data_model {
398 
413  class U_I18N_API Operand : public UObject {
414  public:
423  UBool isVariable() const;
432  UBool isLiteral() const;
441  virtual UBool isNull() const;
451  const UnicodeString& asVariable() const;
461  const Literal& asLiteral() const;
469  Operand() : contents(std::nullopt) {}
479  explicit Operand(const UnicodeString& v) : contents(VariableName(v)) {}
489  explicit Operand(const Literal& l) : contents(l) {}
498  friend inline void swap(Operand& o1, Operand& o2) noexcept {
499  using std::swap;
500  (void) o1;
501  (void) o2;
502  swap(o1.contents, o2.contents);
503  }
510  virtual Operand& operator=(Operand) noexcept;
517  Operand(const Operand&);
524  virtual ~Operand();
525  private:
526  std::optional<std::variant<VariableName, Literal>> contents;
527  }; // class Operand
528 
544  class U_I18N_API Key : public UObject {
545  public:
554  UBool isWildcard() const { return !contents.has_value(); }
564  const Literal& asLiteral() const;
571  Key(const Key& other) : contents(other.contents) {}
579  Key() : contents(std::nullopt) {}
589  explicit Key(const Literal& lit) : contents(lit) {}
598  friend inline void swap(Key& k1, Key& k2) noexcept {
599  using std::swap;
600 
601  swap(k1.contents, k2.contents);
602  }
609  Key& operator=(Key) noexcept;
623  bool operator<(const Key& other) const;
637  bool operator==(const Key& other) const;
644  virtual ~Key();
645  private:
646  /* const */ std::optional<Literal> contents;
647  }; // class Key
648  } // namespace data_model
649 } // namespace message2
650 
652 // Export an explicit template instantiation of the LocalPointer that is used as a
653 // data member of various MFDataModel classes.
654 // (When building DLLs for Windows this is required.)
655 // (See measunit_impl.h, datefmt.h, collationiterator.h, erarules.h and others
656 // for similar examples.)
657 #if U_PF_WINDOWS <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN
660 #endif
662 
663 namespace message2 {
664  namespace data_model {
675  class U_I18N_API SelectorKeys : public UObject {
676  public:
687  std::vector<Key> getKeys() const {
688  return toStdVector<Key>(keys.getAlias(), len);
689  }
699  class U_I18N_API Builder : public UMemory {
700  private:
701  friend class SelectorKeys;
702  UVector* keys; // This is a raw pointer and not a LocalPointer<UVector> to avoid undefined behavior warnings,
703  // since UVector is forward-declared
704  // The vector owns its elements
705  public:
716  Builder& add(Key&& key, UErrorCode& status) noexcept;
729  SelectorKeys build(UErrorCode& status) const;
739  Builder(UErrorCode& status);
746  virtual ~Builder();
747  Builder(const Builder&) = delete;
748  Builder& operator=(const Builder&) = delete;
749  Builder(Builder&&) = delete;
750  Builder& operator=(Builder&&) = delete;
751  }; // class SelectorKeys::Builder
766  bool operator<(const SelectorKeys& other) const;
774  SelectorKeys() : len(0) {}
783  friend inline void swap(SelectorKeys& s1, SelectorKeys& s2) noexcept {
784  using std::swap;
785 
786  swap(s1.len, s2.len);
787  swap(s1.keys, s2.keys);
788  }
795  SelectorKeys(const SelectorKeys& other);
809  virtual ~SelectorKeys();
810  private:
811  friend class Builder;
812  friend class message2::Checker;
813  friend class message2::MessageFormatter;
814  friend class message2::Serializer;
815 
816  /* const */ LocalArray<Key> keys;
817  /* const */ int32_t len;
818 
819  const Key* getKeysInternal() const;
820  SelectorKeys(const UVector& ks, UErrorCode& status);
821  }; // class SelectorKeys
822 
823 
824  } // namespace data_model
825 
826 
827  namespace data_model {
828  class Operator;
829 
838  class U_I18N_API Option : public UObject {
839  public:
848  const Operand& getValue() const { return rand; }
857  const UnicodeString& getName() const { return name; }
868  Option(const UnicodeString& n, Operand&& r) : name(n), rand(std::move(r)) {}
876  Option() {}
885  friend inline void swap(Option& o1, Option& o2) noexcept {
886  using std::swap;
887 
888  swap(o1.name, o2.name);
889  swap(o1.rand, o2.rand);
890  }
897  Option(const Option& other);
904  Option& operator=(Option other) noexcept;
911  virtual ~Option();
912  private:
913  /* const */ UnicodeString name;
914  /* const */ Operand rand;
915  }; // class Option
916  } // namespace data_model
917 } // namespace message2
918 
920 // Export an explicit template instantiation of the LocalPointer that is used as a
921 // data member of various MFDataModel classes.
922 // (When building DLLs for Windows this is required.)
923 // (See measunit_impl.h, datefmt.h, collationiterator.h, erarules.h and others
924 // for similar examples.)
925 #if U_PF_WINDOWS <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN
928 #endif
930 
931 namespace message2 {
932  namespace data_model {
933  // Internal only
934  #ifndef U_IN_DOXYGEN
935  // Options
936  // This is a wrapper class around a vector of options that provides lookup operations
937  class U_I18N_API OptionMap : public UObject {
938  public:
939  int32_t size() const;
940  // Needs to take an error code b/c an earlier copy might have failed
941  const Option& getOption(int32_t, UErrorCode&) const;
942  friend inline void swap(OptionMap& m1, OptionMap& m2) noexcept {
943  using std::swap;
944 
945  swap(m1.bogus, m2.bogus);
946  swap(m1.options, m2.options);
947  swap(m1.len, m2.len);
948  }
949  OptionMap() : len(0) {}
950  OptionMap(const OptionMap&);
951  OptionMap& operator=(OptionMap);
952  std::vector<Option> getOptions() const {
953  return toStdVector<Option>(options.getAlias(), len);
954  }
955  OptionMap(const UVector&, UErrorCode&);
956  OptionMap(Option*, int32_t);
957  virtual ~OptionMap();
958 
959  class U_I18N_API Builder : public UObject {
960  private:
961  UVector* options;
962  bool checkDuplicates = true;
963  public:
964  Builder& add(Option&& opt, UErrorCode&);
965  Builder(UErrorCode&);
966  static Builder attributes(UErrorCode&);
967  // As this class is private, build() is destructive
968  OptionMap build(UErrorCode&);
969  friend inline void swap(Builder& m1, Builder& m2) noexcept {
970  using std::swap;
971 
972  swap(m1.options, m2.options);
973  swap(m1.checkDuplicates, m2.checkDuplicates);
974  }
975  Builder(Builder&&);
976  Builder(const Builder&) = delete;
977  Builder& operator=(Builder) noexcept;
978  virtual ~Builder();
979  }; // class OptionMap::Builder
980  private:
981  friend class message2::Serializer;
982 
983  bool bogus = false;
984  LocalArray<Option> options;
985  int32_t len;
986  }; // class OptionMap
987  #endif
988 
989  // Internal use only
990  #ifndef U_IN_DOXYGEN
991  class U_I18N_API Callable : public UObject {
992  public:
993  friend inline void swap(Callable& c1, Callable& c2) noexcept {
994  using std::swap;
995 
996  swap(c1.name, c2.name);
997  swap(c1.options, c2.options);
998  }
999  const FunctionName& getName() const { return name; }
1000  const OptionMap& getOptions() const { return options; }
1001  Callable(const FunctionName& f, const OptionMap& opts) : name(f), options(opts) {}
1002  Callable& operator=(Callable) noexcept;
1003  Callable(const Callable&);
1004  Callable() = default;
1005  virtual ~Callable();
1006  private:
1007  /* const */ FunctionName name;
1008  /* const */ OptionMap options;
1009  };
1010  #endif
1011  } // namespace data_model
1012 } // namespace message2
1013 
1014 U_NAMESPACE_END
1015 
1017 // Export an explicit template instantiation of the std::variant that is used as a
1018 // data member of various MFDataModel classes.
1019 // (When building DLLs for Windows this is required.)
1020 // (See measunit_impl.h, datefmt.h, collationiterator.h, erarules.h and others
1021 // for similar examples.)
1022 #if U_PF_WINDOWS <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN
1023 #if defined(U_REAL_MSVC) && defined(_MSVC_STL_VERSION)
1024 template class U_I18N_API std::_Variant_storage_<false, icu::message2::data_model::Reserved,icu::message2::data_model::Callable>;
1025 #endif
1026 template class U_I18N_API std::variant<icu::message2::data_model::Reserved,icu::message2::data_model::Callable>;
1027 #endif
1029 
1030 U_NAMESPACE_BEGIN
1031 
1032 namespace message2 {
1033  namespace data_model {
1049  class U_I18N_API Operator : public UObject {
1050  public:
1059  UBool isReserved() const { return std::holds_alternative<Reserved>(contents); }
1079  const Reserved& asReserved() const;
1089  std::vector<Option> getOptions() const {
1090  const Callable* f = std::get_if<Callable>(&contents);
1091  // This case should never happen, as the precondition is !isReserved()
1092  if (f == nullptr) { return {}; }
1093  const OptionMap& opts = f->getOptions();
1094  return opts.getOptions();
1095  }
1105  class U_I18N_API Builder : public UMemory {
1106  private:
1107  friend class Operator;
1108  bool isReservedSequence = false;
1109  bool hasFunctionName = false;
1110  bool hasOptions = false;
1111  Reserved asReserved;
1112  FunctionName functionName;
1113  OptionMap::Builder options;
1114  public:
1153  Builder& addOption(const UnicodeString &key, Operand&& value, UErrorCode& status) noexcept;
1188  virtual ~Builder();
1189  Builder(const Builder&) = delete;
1190  Builder& operator=(const Builder&) = delete;
1191  Builder(Builder&&) = delete;
1192  Builder& operator=(Builder&&) = delete;
1193  }; // class Operator::Builder
1200  Operator(const Operator& other) noexcept;
1209  friend inline void swap(Operator& o1, Operator& o2) noexcept {
1210  using std::swap;
1211 
1212  swap(o1.contents, o2.contents);
1213  }
1228  Operator() : contents(Reserved()) {}
1235  virtual ~Operator();
1236  private:
1237  friend class Binding;
1238  friend class Builder;
1239  friend class message2::Checker;
1240  friend class message2::MessageFormatter;
1241  friend class message2::Serializer;
1242 
1243  // Function call constructor
1244  Operator(const FunctionName& f, const UVector& options, UErrorCode&);
1245  // Reserved sequence constructor
1246  Operator(const Reserved& r) : contents(r) {}
1247 
1248  const OptionMap& getOptionsInternal() const;
1249  Operator(const FunctionName&, const OptionMap&);
1250  /* const */ std::variant<Reserved, Callable> contents;
1251  }; // class Operator
1252  } // namespace data_model
1253 } // namespace message2
1254 
1255 U_NAMESPACE_END
1256 
1258 // Export an explicit template instantiation of the std::optional that is used as a
1259 // data member of various MFDataModel classes.
1260 // (When building DLLs for Windows this is required.)
1261 // (See measunit_impl.h, datefmt.h, collationiterator.h, erarules.h and others
1262 // for similar examples.)
1263 #if U_PF_WINDOWS <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN
1264 template class U_I18N_API std::optional<icu::message2::data_model::Operator>;
1265 template class U_I18N_API std::optional<icu::message2::data_model::Reserved>;
1266 #endif
1268 
1269 U_NAMESPACE_BEGIN
1270 
1271 namespace message2 {
1272  namespace data_model {
1273  // Internal only
1274  typedef enum UMarkupType {
1275  UMARKUP_OPEN = 0,
1276  UMARKUP_CLOSE,
1277  UMARKUP_STANDALONE,
1278  UMARKUP_COUNT
1279  } UMarkupType;
1280 
1291  class U_I18N_API Markup : public UObject {
1292  public:
1301  UBool isOpen() const { return (type == UMARKUP_OPEN); }
1310  UBool isClose() const { return (type == UMARKUP_CLOSE); }
1319  UBool isStandalone() const { return (type == UMARKUP_STANDALONE); }
1328  const UnicodeString& getName() const { return name; }
1337  std::vector<Option> getOptions() const { return options.getOptions(); }
1346  std::vector<Option> getAttributes() const { return attributes.getOptions(); }
1354  Markup() {}
1361  virtual ~Markup();
1371  class U_I18N_API Builder : public UMemory {
1372  private:
1373  friend class Markup;
1374 
1375  UnicodeString name;
1376  OptionMap::Builder options;
1377  OptionMap::Builder attributes;
1378  UMarkupType type = UMARKUP_COUNT;
1379  public:
1389  Builder& setName(const UnicodeString& n) { name = n; return *this; }
1398  Builder& setOpen() { type = UMARKUP_OPEN; return *this; }
1407  Builder& setClose() { type = UMARKUP_CLOSE; return *this; }
1416  Builder& setStandalone() { type = UMARKUP_STANDALONE; return *this; }
1428  Builder& addOption(const UnicodeString &key, Operand&& value, UErrorCode& status);
1440  Builder& addAttribute(const UnicodeString &key, Operand&& value, UErrorCode& status);
1475  virtual ~Builder();
1476  Builder(const Builder&) = delete;
1477  Builder& operator=(const Builder&) = delete;
1478  Builder(Builder&&) = delete;
1479  Builder& operator=(Builder&&) = delete;
1480  }; // class Markup::Builder
1481 
1482  private:
1483  friend class Builder;
1484  friend class message2::Serializer;
1485 
1486  UMarkupType type;
1487  UnicodeString name;
1488  OptionMap options;
1489  OptionMap attributes;
1490  const OptionMap& getOptionsInternal() const { return options; }
1491  const OptionMap& getAttributesInternal() const { return attributes; }
1492  Markup(UMarkupType, UnicodeString, OptionMap&&, OptionMap&&);
1493  }; // class Markup
1494 
1508  class U_I18N_API Expression : public UObject {
1509  public:
1557  const Operator* getOperator(UErrorCode& status) const;
1567  const Operand& getOperand() const;
1576  std::vector<Option> getAttributes() const { return attributes.getOptions(); }
1586  class U_I18N_API Builder : public UMemory {
1587  private:
1588  friend class Expression;
1589 
1590  bool hasOperand = false;
1591  bool hasOperator = false;
1592  Operand rand;
1593  Operator rator;
1594  OptionMap::Builder attributes;
1595  public:
1627  Builder& addAttribute(const UnicodeString &key, Operand&& value, UErrorCode& status);
1662  virtual ~Builder();
1663  Builder(const Builder&) = delete;
1664  Builder& operator=(const Builder&) = delete;
1665  Builder(Builder&&) = delete;
1666  Builder& operator=(Builder&&) = delete;
1667  }; // class Expression::Builder
1676  friend inline void swap(Expression& e1, Expression& e2) noexcept {
1677  using std::swap;
1678 
1679  swap(e1.rator, e2.rator);
1680  swap(e1.rand, e2.rand);
1681  swap(e1.attributes, e2.attributes);
1682  }
1689  Expression(const Expression& other);
1711  virtual ~Expression();
1712  private:
1713  friend class message2::Serializer;
1714 
1715  /*
1716  Internally, an expression is represented as the application of an optional operator to an operand.
1717  The operand is always present; for function calls with no operand, it's represented
1718  as an operand for which `isNull()` is true.
1719 
1720  Operator | Operand
1721  --------------------------------
1722  { |42| :fun opt=value } => (FunctionName=fun, | Literal(quoted=true, contents="42")
1723  options={opt: value})
1724  { abcd } => null | Literal(quoted=false, contents="abcd")
1725  { : fun opt=value } => (FunctionName=fun,
1726  options={opt: value}) | NullOperand()
1727  */
1728 
1729  Expression(const Operator &rAtor, const Operand &rAnd, const OptionMap& attrs) : rator(rAtor), rand(rAnd), attributes(attrs) {}
1730  Expression(const Operand &rAnd, const OptionMap& attrs) : rator(std::nullopt), rand(Operand(rAnd)), attributes(attrs) {}
1731  Expression(const Operator &rAtor, const OptionMap& attrs) : rator(rAtor), rand(), attributes(attrs) {}
1732  /* const */ std::optional<Operator> rator;
1733  /* const */ Operand rand;
1734  /* const */ OptionMap attributes;
1735  const OptionMap& getAttributesInternal() const { return attributes; }
1736  }; // class Expression
1737  } // namespace data_model
1738 } // namespace message2
1739 
1741 // Export an explicit template instantiation of the LocalPointer that is used as a
1742 // data member of various MFDataModel classes.
1743 // (When building DLLs for Windows this is required.)
1744 // (See measunit_impl.h, datefmt.h, collationiterator.h, erarules.h and others
1745 // for similar examples.)
1746 #if U_PF_WINDOWS <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN
1747 template class U_I18N_API LocalPointerBase<message2::data_model::Expression>;
1748 template class U_I18N_API LocalArray<message2::data_model::Expression>;
1749 #endif
1751 
1752 namespace message2 {
1753  namespace data_model {
1768  public:
1777  const UnicodeString& getKeyword() const { return keyword; }
1789  const Reserved* getBody(UErrorCode& status) const;
1798  std::vector<Expression> getExpressions() const {
1799  if (expressionsLen <= 0 || !expressions.isValid()) {
1800  // This case should never happen, but we can't use an assertion here
1801  return {};
1802  }
1803  return toStdVector<Expression>(expressions.getAlias(), expressionsLen);
1804  }
1814  class U_I18N_API Builder : public UMemory {
1815  private:
1816  friend class UnsupportedStatement;
1817  friend class message2::Parser;
1818 
1819  UnicodeString keyword;
1820  std::optional<Reserved> body;
1821  UVector* expressions; // Vector of expressions;
1822  // not a LocalPointer for
1823  // the same reason as in `SelectorKeys::builder`
1824  public:
1888  virtual ~Builder();
1889  Builder(const Builder&) = delete;
1890  Builder& operator=(const Builder&) = delete;
1891  Builder(Builder&&) = delete;
1892  Builder& operator=(Builder&&) = delete;
1893  }; // class UnsupportedStatement::Builder
1902  friend inline void swap(UnsupportedStatement& s1, UnsupportedStatement& s2) noexcept {
1903  using std::swap;
1904 
1905  swap(s1.keyword, s2.keyword);
1906  swap(s1.body, s2.body);
1907  swap(s1.expressions, s2.expressions);
1908  swap(s1.expressionsLen, s2.expressionsLen);
1909  }
1939  private:
1940  friend class message2::Serializer;
1941 
1942  /* const */ UnicodeString keyword;
1943  /* const */ std::optional<Reserved> body;
1944  /* const */ LocalArray<Expression> expressions;
1945  /* const */ int32_t expressionsLen = 0;
1946 
1947  const Expression* getExpressionsInternal() const { return expressions.getAlias(); }
1948 
1949  UnsupportedStatement(const UnicodeString&, const std::optional<Reserved>&, const UVector&, UErrorCode&);
1950  }; // class UnsupportedStatement
1951 
1952  class Pattern;
1953 
1954  // Despite the comments, `PatternPart` is internal-only
1965  class PatternPart : public UObject {
1966  public:
1975  UBool isText() const { return std::holds_alternative<UnicodeString>(piece); }
1984  UBool isMarkup() const { return std::holds_alternative<Markup>(piece); }
1993  UBool isExpression() const { return std::holds_alternative<Expression>(piece); }
2003  const Expression& contents() const;
2013  const Markup& asMarkup() const;
2023  const UnicodeString& asText() const;
2032  friend inline void swap(PatternPart& p1, PatternPart& p2) noexcept {
2033  using std::swap;
2034 
2035  swap(p1.piece, p2.piece);
2036  }
2043  PatternPart(const PatternPart& other);
2057  virtual ~PatternPart();
2067  explicit PatternPart(const UnicodeString& t) : piece(t) {}
2077  explicit PatternPart(Expression&& e) : piece(e) {}
2087  explicit PatternPart(Markup&& m) : piece(m) {}
2095  PatternPart() = default;
2096  private:
2097  friend class Pattern;
2098 
2099  std::variant<UnicodeString, Expression, Markup> piece;
2100  }; // class PatternPart
2101  } // namespace data_model
2102 } // namespace message2
2103 
2105 // Export an explicit template instantiation of the LocalPointer that is used as a
2106 // data member of various MFDataModel classes.
2107 // (When building DLLs for Windows this is required.)
2108 // (See measunit_impl.h, datefmt.h, collationiterator.h, erarules.h and others
2109 // for similar examples.)
2110 #if U_PF_WINDOWS <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN
2115 #endif
2117 
2118 namespace message2 {
2119  namespace data_model {
2130  class U_I18N_API Pattern : public UObject {
2131  private:
2132  friend class PatternPart;
2133 
2134  public:
2135  struct Iterator;
2145  Iterator begin() const {
2146  return Iterator(this, 0);
2147  }
2157  Iterator end() const {
2158  return Iterator(this, len);
2159  }
2169  class U_I18N_API Builder : public UMemory {
2170  private:
2171  friend class Pattern;
2172 
2173  UVector* parts; // Not a LocalPointer for the same reason as in `SelectorKeys::Builder`
2174 
2175  public:
2186  Builder& add(Expression&& part, UErrorCode& status) noexcept;
2197  Builder& add(Markup&& part, UErrorCode& status) noexcept;
2208  Builder& add(UnicodeString&& part, UErrorCode& status) noexcept;
2221  Pattern build(UErrorCode& status) const noexcept;
2238  virtual ~Builder();
2239  Builder(const Builder&) = delete;
2240  Builder& operator=(const Builder&) = delete;
2241  Builder(Builder&&) = delete;
2242  Builder& operator=(Builder&&) = delete;
2243  }; // class Pattern::Builder
2244 
2252  Pattern() : parts(LocalArray<PatternPart>()) {}
2261  friend inline void swap(Pattern& p1, Pattern& p2) noexcept {
2262  using std::swap;
2263 
2264  swap(p1.bogus, p2.bogus);
2265  swap(p1.len, p2.len);
2266  swap(p1.parts, p2.parts);
2267  }
2274  Pattern(const Pattern& other);
2288  virtual ~Pattern();
2289 
2300  private:
2301  using iterator_category = std::forward_iterator_tag;
2302  using difference_type = std::ptrdiff_t;
2303  using value_type = std::variant<UnicodeString, Expression, Markup>;
2304  using pointer = value_type*;
2305  using reference = const value_type&;
2306 
2307  friend class Pattern;
2308  Iterator(const Pattern* p, int32_t i) : pos(i), pat(p) {}
2309  friend bool operator== (const Iterator& a, const Iterator& b) { return (a.pat == b.pat && a.pos == b.pos); }
2310 
2311  int32_t pos;
2312  const Pattern* pat;
2313 
2314  public:
2321  reference operator*() const {
2322  const PatternPart& part = pat->parts[pos];
2323  return patternContents(part);
2324  }
2331  Iterator operator++() { pos++; return *this; }
2338  friend bool operator!= (const Iterator& a, const Iterator& b) { return !(a == b); }
2339  }; // struct Iterator
2340 
2341  private:
2342  friend class Builder;
2343  friend class message2::MessageFormatter;
2344  friend class message2::Serializer;
2345 
2346  // Set to true if a copy constructor fails;
2347  // needed in order to distinguish an uninitialized
2348  // Pattern from a 0-length pattern
2349  bool bogus = false;
2350 
2351  // Possibly-empty array of parts
2352  int32_t len = 0;
2354 
2355  Pattern(const UVector& parts, UErrorCode& status);
2356  // Helper
2357  static void initParts(Pattern&, const Pattern&);
2358 
2367  int32_t numParts() const;
2378  const PatternPart& getPart(int32_t i) const;
2379 
2380  // Gets around not being able to declare Pattern::Iterator as a friend
2381  // in PatternPart
2382  static const std::variant<UnicodeString, Expression, Markup>&
2383  patternContents(const PatternPart& p) { return p.piece; }
2384  }; // class Pattern
2385 
2396  class U_I18N_API Variant : public UObject {
2397  public:
2406  const Pattern& getPattern() const { return p; }
2415  const SelectorKeys& getKeys() const { return k; }
2427  Variant(const SelectorKeys& keys, Pattern&& pattern) : k(keys), p(std::move(pattern)) {}
2436  friend inline void swap(Variant& v1, Variant& v2) noexcept {
2437  using std::swap;
2438 
2439  swap(v1.k, v2.k);
2440  swap(v1.p, v2.p);
2441  }
2448  Variant& operator=(Variant other) noexcept;
2456  Variant() = default;
2463  Variant(const Variant&);
2470  virtual ~Variant();
2471  private:
2472  /* const */ SelectorKeys k;
2473  /* const */ Pattern p;
2474  }; // class Variant
2475  } // namespace data_model
2476 
2477  namespace data_model {
2488  class U_I18N_API Binding : public UObject {
2489  public:
2498  const Expression& getValue() const;
2507  const VariableName& getVariable() const { return var; }
2522  static Binding input(UnicodeString&& variableName, Expression&& rhs, UErrorCode& errorCode);
2530  UBool isLocal() const { return local; }
2540  Binding(const VariableName& v, Expression&& e) : var(v), expr(std::move(e)), local(true), annotation(nullptr) {}
2549  friend inline void swap(Binding& b1, Binding& b2) noexcept {
2550  using std::swap;
2551 
2552  swap(b1.var, b2.var);
2553  swap(b1.expr, b2.expr);
2554  swap(b1.local, b2.local);
2555  b1.updateAnnotation();
2556  b2.updateAnnotation();
2557  }
2564  Binding(const Binding& other);
2579  Binding() : local(true) {}
2586  virtual ~Binding();
2587  private:
2588  friend class message2::Checker;
2589  friend class message2::MessageFormatter;
2590  friend class message2::Parser;
2591  friend class message2::Serializer;
2592 
2593  /* const */ VariableName var;
2594  /* const */ Expression expr;
2595  /* const */ bool local;
2596 
2597  // The following field is always nullptr for a local
2598  // declaration, and possibly nullptr for an .input declaration
2599  // If non-null, the referent is a member of `expr` so
2600  // its lifetime is the same as the lifetime of the enclosing Binding
2601  // (as long as there's no mutation)
2602  const Callable* annotation = nullptr;
2603 
2604  const OptionMap& getOptionsInternal() const;
2605 
2606  bool hasAnnotation() const { return !local && (annotation != nullptr); }
2607  void updateAnnotation();
2608  }; // class Binding
2609  } // namespace data_model
2610 } // namespace message2
2611 
2613 // Export an explicit template instantiation of the LocalPointer that is used as a
2614 // data member of various MFDataModel classes.
2615 // (When building DLLs for Windows this is required.)
2616 // (See measunit_impl.h, datefmt.h, collationiterator.h, erarules.h and others
2617 // for similar examples.)
2618 #if U_PF_WINDOWS <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN
2619 template class U_I18N_API LocalPointerBase<message2::data_model::Variant>;
2620 template class U_I18N_API LocalPointerBase<message2::data_model::Binding>;
2621 template class U_I18N_API LocalArray<message2::data_model::Variant>;
2622 template class U_I18N_API LocalArray<message2::data_model::Binding>;
2623 #endif
2625 
2626 namespace message2 {
2627  using namespace data_model;
2628 
2629 
2630  // Internal only
2631 
2632  class MFDataModel;
2633 
2634  #ifndef U_IN_DOXYGEN
2635  class Matcher : public UObject {
2636  public:
2637  Matcher& operator=(Matcher);
2638  Matcher(const Matcher&);
2647  friend inline void swap(Matcher& m1, Matcher& m2) noexcept {
2648  using std::swap;
2649 
2650  if (m1.bogus) {
2651  m2.bogus = true;
2652  return;
2653  }
2654  if (m2.bogus) {
2655  m1.bogus = true;
2656  return;
2657  }
2658  swap(m1.selectors, m2.selectors);
2659  swap(m1.numSelectors, m2.numSelectors);
2660  swap(m1.variants, m2.variants);
2661  swap(m1.numVariants, m2.numVariants);
2662  }
2663  virtual ~Matcher();
2664  private:
2665 
2666  friend class MFDataModel;
2667 
2668  Matcher(Expression* ss, int32_t ns, Variant* vs, int32_t nv);
2669  Matcher() {}
2670 
2671  // A Matcher may have numSelectors=0 and numVariants=0
2672  // (this is a data model error, but it's representable).
2673  // So we have to keep a separate flag to track failed copies.
2674  bool bogus = false;
2675 
2676  // The expressions that are being matched on.
2677  LocalArray<Expression> selectors;
2678  // The number of selectors
2679  int32_t numSelectors = 0;
2680  // The list of `when` clauses (case arms).
2681  LocalArray<Variant> variants;
2682  // The number of variants
2683  int32_t numVariants = 0;
2684  }; // class Matcher
2685  #endif
2686 } // namespace message2
2687 
2688 U_NAMESPACE_END
2689 
2691 // Export an explicit template instantiation of the std::variant that is used as a
2692 // data member of various MFDataModel classes.
2693 // (When building DLLs for Windows this is required.)
2694 // (See measunit_impl.h, datefmt.h, collationiterator.h, erarules.h and others
2695 // for similar examples.)
2696 #if U_PF_WINDOWS <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN
2697 #if defined(U_REAL_MSVC) && defined(_MSVC_STL_VERSION)
2698 template class U_I18N_API std::_Variant_storage_<false, icu::message2::Matcher,icu::message2::data_model::Pattern>;
2699 #endif
2700 template class U_I18N_API std::variant<icu::message2::Matcher,icu::message2::data_model::Pattern>;
2701 #endif
2703 
2704 U_NAMESPACE_BEGIN
2705 
2706 namespace message2 {
2707  // -----------------------------------------------------------------------
2708  // Public MFDataModel class
2709 
2726  class U_I18N_API MFDataModel : public UMemory {
2727  /*
2728  Classes that represent nodes in the data model are nested inside the
2729  `MFDataModel` class.
2730 
2731  Classes such as `Expression`, `Pattern` and `VariantMap` are immutable and
2732  are constructed using the builder pattern.
2733 
2734  Most classes representing nodes have copy constructors. This is because builders
2735  contain immutable data that must be copied when calling `build()`, since the builder
2736  could go out of scope before the immutable result of the builder does. Copying is
2737  also necessary to prevent unexpected mutation if intermediate builders are saved
2738  and mutated again after calling `build()`.
2739 
2740  The copy constructors perform a deep copy, for example by copying the entire
2741  list of options for an `Operator` (and copying the entire underlying vector.)
2742  Some internal fields should be `const`, but are declared as non-`const` to make
2743  the copy constructor simpler to implement. (These are noted throughout.) In
2744  other words, those fields are `const` except during the execution of a copy
2745  constructor.
2746 
2747  On the other hand, intermediate `Builder` methods that return a `Builder&`
2748  mutate the state of the builder, so in code like:
2749 
2750  Expression::Builder& exprBuilder = Expression::builder()-> setOperand(foo);
2751  Expression::Builder& exprBuilder2 = exprBuilder.setOperator(bar);
2752 
2753  the call to `setOperator()` would mutate `exprBuilder`, since `exprBuilder`
2754  and `exprBuilder2` are references to the same object.
2755 
2756  An alternate choice would be to make `build()` destructive, so that copying would
2757  be unnecessary. Or, both copying and moving variants of `build()` could be
2758  provided. Copying variants of the intermediate `Builder` methods could be
2759  provided as well, if this proved useful.
2760  */
2761  public:
2770  std::vector<Binding> getLocalVariables() const {
2771  std::vector<Binding> result;
2772  if (!bogus) {
2773  return toStdVector<Binding>(bindings.getAlias(), bindingsLen);
2774  }
2775  return {};
2776  }
2785  const std::vector<Expression> getSelectors() const {
2786  if (std::holds_alternative<Pattern>(body)) {
2787  return {};
2788  }
2789  const Matcher* match = std::get_if<Matcher>(&body);
2790  // match must be non-null, given the previous check
2791  return toStdVector<Expression>(match->selectors.getAlias(), match->numSelectors);
2792  }
2801  std::vector<Variant> getVariants() const {
2802  // Return empty vector if no variants
2803  if (std::holds_alternative<Pattern>(body)) {
2804  return {};
2805  }
2806  const Matcher* match = std::get_if<Matcher>(&body);
2807  // match must be non-null, given the previous check
2808  return toStdVector<Variant>(match->variants.getAlias(), match->numVariants);
2809  return {};
2810  }
2819  std::vector<UnsupportedStatement> getUnsupportedStatements() const {
2820  std::vector<UnsupportedStatement> result;
2821  if (!bogus) {
2822  return toStdVector<UnsupportedStatement>(unsupportedStatements.getAlias(), unsupportedStatementsLen);
2823  }
2824  return {};
2825  }
2835  const Pattern& getPattern() const;
2836 
2844  class U_I18N_API Builder;
2845 
2862  friend inline void swap(MFDataModel& m1, MFDataModel& m2) noexcept {
2863  using std::swap;
2864 
2865  if (m1.bogus) {
2866  m2.bogus = true;
2867  return;
2868  }
2869  if (m2.bogus) {
2870  m1.bogus = true;
2871  return;
2872  }
2873  swap(m1.body, m2.body);
2874  swap(m1.bindings, m2.bindings);
2875  swap(m1.bindingsLen, m2.bindingsLen);
2876  swap(m1.unsupportedStatements, m2.unsupportedStatements);
2877  swap(m1.unsupportedStatementsLen, m2.unsupportedStatementsLen);
2878  }
2892  MFDataModel(const MFDataModel& other);
2899  virtual ~MFDataModel();
2900 
2908  class U_I18N_API Builder : public UMemory {
2909  private:
2910  friend class MFDataModel;
2911 
2912  void checkDuplicate(const VariableName&, UErrorCode&) const;
2913  void buildSelectorsMessage(UErrorCode&);
2914  bool hasPattern = true;
2915  bool hasSelectors = false;
2916  Pattern pattern;
2917  // The following members are not LocalPointers for the same reason as in SelectorKeys::Builder
2918  UVector* selectors = nullptr;
2919  UVector* variants = nullptr;
2920  UVector* bindings = nullptr;
2921  UVector* unsupportedStatements = nullptr;
2922  public:
2958  Builder& addSelector(Expression&& selector, UErrorCode& errorCode) noexcept;
2971  Builder& addVariant(SelectorKeys&& keys, Pattern&& pattern, UErrorCode& errorCode) noexcept;
3003  MFDataModel build(UErrorCode& status) const noexcept;
3023  virtual ~Builder();
3024  Builder(const Builder&) = delete;
3025  Builder& operator=(const Builder&) = delete;
3026  Builder(Builder&&) = delete;
3027  Builder& operator=(Builder&&) = delete;
3028  }; // class Builder
3029 
3030  private:
3031  friend class Checker;
3032  friend class MessageFormatter;
3033  friend class Serializer;
3034 
3035  Pattern empty; // Provided so that `getPattern()` can return a result
3036  // if called on a selectors message
3037  bool hasPattern() const { return std::holds_alternative<Pattern>(body); }
3038 
3039  bool bogus = false; // Set if a copy constructor fails
3040 
3041  // A message body is either a matcher (selector list and variant list),
3042  // or a single pattern
3043  std::variant<Matcher, Pattern> body;
3044 
3045  // Bindings for local variables
3046  /* const */ LocalArray<Binding> bindings;
3047  int32_t bindingsLen = 0;
3048 
3049  // Unsupported statements
3050  // (Treated as a type of `declaration` in the data model spec;
3051  // stored separately for convenience)
3052  /* const */ LocalArray<UnsupportedStatement> unsupportedStatements;
3053  int32_t unsupportedStatementsLen = 0;
3054 
3055  const Binding* getLocalVariablesInternal() const;
3056  const Expression* getSelectorsInternal() const;
3057  const Variant* getVariantsInternal() const;
3058  const UnsupportedStatement* getUnsupportedStatementsInternal() const;
3059 
3060  int32_t numSelectors() const {
3061  const Matcher* matcher = std::get_if<Matcher>(&body);
3062  return (matcher == nullptr ? 0 : matcher->numSelectors);
3063  }
3064  int32_t numVariants() const {
3065  const Matcher* matcher = std::get_if<Matcher>(&body);
3066  return (matcher == nullptr ? 0 : matcher->numVariants);
3067  }
3068 
3069  // Helper
3070  void initBindings(const Binding*);
3071 
3072  MFDataModel(const Builder& builder, UErrorCode&) noexcept;
3073  }; // class MFDataModel
3074 
3075 } // namespace message2
3076 
3077 U_NAMESPACE_END
3078 
3079 #endif // U_HIDE_DEPRECATED_API
3080 
3081 #endif /* #if !UCONFIG_NO_MF2 */
3082 
3083 #endif /* #if !UCONFIG_NO_FORMATTING */
3084 
3085 #endif /* U_SHOW_CPLUSPLUS_API */
3086 
3087 #endif // MESSAGEFORMAT_DATA_MODEL_H
3088 
3089 // eof
3090 
"Smart pointer" class, deletes objects via the C++ array delete[] operator.
Definition: localpointer.h:366
"Smart pointer" base class; do not use directly: use LocalPointer etc.
Definition: localpointer.h:68
T * getAlias() const
Access without ownership change.
Definition: localpointer.h:122
UMemory is the common ICU base class.
Definition: uobject.h:115
UObject is the common ICU "boilerplate" class.
Definition: uobject.h:223
UnicodeString is a string class that stores Unicode characters directly and provides similar function...
Definition: unistr.h:296
The mutable MFDataModel::Builder class allows the data model to be constructed incrementally.
Builder(UErrorCode &status)
Default constructor.
Builder & setPattern(Pattern &&pattern)
Sets the body of the message as a pattern.
Builder & addVariant(SelectorKeys &&keys, Pattern &&pattern, UErrorCode &errorCode) noexcept
Adds a single variant.
Builder & addSelector(Expression &&selector, UErrorCode &errorCode) noexcept
Adds a selector expression.
MFDataModel build(UErrorCode &status) const noexcept
Constructs a new immutable data model.
Builder & addUnsupportedStatement(UnsupportedStatement &&s, UErrorCode &status)
Adds an unsupported statement.
Builder & addBinding(Binding &&b, UErrorCode &status)
Adds a binding, There must not already be a binding with the same name.
The MFDataModel class describes a parsed representation of the text of a message.
virtual ~MFDataModel()
Destructor.
std::vector< Variant > getVariants() const
Accesses the variants.
const std::vector< Expression > getSelectors() const
Accesses the selectors.
MFDataModel & operator=(MFDataModel) noexcept
Assignment operator.
MFDataModel()
Default constructor.
std::vector< UnsupportedStatement > getUnsupportedStatements() const
Accesses the unsupported statements for this data model.
friend void swap(MFDataModel &m1, MFDataModel &m2) noexcept
Non-member swap function.
std::vector< Binding > getLocalVariables() const
Accesses the local variable declarations for this data model.
MFDataModel(const MFDataModel &other)
Copy constructor.
A Binding pairs a variable name with an expression.
Binding & operator=(Binding) noexcept
Copy assignment operator.
UBool isLocal() const
Returns true if and only if this binding represents a local declaration.
Binding(const Binding &other)
Copy constructor.
const Expression & getValue() const
Accesses the right-hand side of a binding.
const VariableName & getVariable() const
Accesses the left-hand side of the binding.
static Binding input(UnicodeString &&variableName, Expression &&rhs, UErrorCode &errorCode)
Constructor for input binding.
Binding(const VariableName &v, Expression &&e)
Constructor.
friend void swap(Binding &b1, Binding &b2) noexcept
Non-member swap function.
The mutable Expression::Builder class allows the operator to be constructed incrementally.
Expression build(UErrorCode &status)
Constructs a new immutable Expression using the operand and operator that were previously set.
Builder & addAttribute(const UnicodeString &key, Operand &&value, UErrorCode &status)
Adds a single attribute.
Builder & setOperator(Operator &&rAtor)
Sets the operator of this expression.
Builder & setOperand(Operand &&rAnd)
Sets the operand of this expression.
Builder(UErrorCode &status)
Default constructor.
The Expression class corresponds to the expression nonterminal in the MessageFormat 2 grammar and the...
Expression & operator=(Expression) noexcept
Assignment operator.
const Operator * getOperator(UErrorCode &status) const
Accesses the function or reserved sequence annotating this expression.
UBool isFunctionCall() const
Checks if this expression has a function annotation (with or without an operand).
std::vector< Option > getAttributes() const
Gets the attributes of this expression.
UBool isStandaloneAnnotation() const
Checks if this expression is an annotation with no operand.
UBool isReserved() const
Returns true if and only if this expression is annotated with a reserved sequence.
const Operand & getOperand() const
Accesses the operand of this expression.
Expression(const Expression &other)
Copy constructor.
friend void swap(Expression &e1, Expression &e2) noexcept
Non-member swap function.
The Key class corresponds to the key nonterminal in the MessageFormat 2 grammar, https://github....
Key(const Key &other)
Copy constructor.
UBool isWildcard() const
Determines if this is a wildcard key.
Key & operator=(Key) noexcept
Assignment operator.
const Literal & asLiteral() const
Returns the contents of this key as a literal.
virtual ~Key()
Destructor.
Key(const Literal &lit)
Literal key constructor.
Key()
Wildcard constructor; constructs a Key representing the catchall or wildcard key, '*'.
bool operator<(const Key &other) const
Less than operator.
bool operator==(const Key &other) const
Equality operator.
friend void swap(Key &k1, Key &k2) noexcept
Non-member swap function.
The Literal class corresponds to the literal nonterminal in the MessageFormat 2 grammar,...
UBool isQuoted() const
Determines if this literal appeared as a quoted literal in the message.
friend void swap(Literal &l1, Literal &l2) noexcept
Non-member swap function.
Literal(UBool q, const UnicodeString &s)
Literal constructor.
const UnicodeString & unquoted() const
Returns the parsed string contents of this literal.
UnicodeString quoted() const
Returns the quoted representation of this literal (enclosed in '|' characters)
Literal()=default
Default constructor.
bool operator<(const Literal &other) const
Less than operator.
Literal & operator=(Literal) noexcept
Assignment operator.
Literal(const Literal &other)
Copy constructor.
bool operator==(const Literal &other) const
Equality operator.
The mutable Markup::Builder class allows the markup to be constructed incrementally.
Builder & setName(const UnicodeString &n)
Sets the name of this markup.
Builder & setStandalone()
Sets this to be a standalone markup.
Builder(UErrorCode &status)
Default constructor.
Builder & setOpen()
Sets this to be an opening markup.
Builder & addOption(const UnicodeString &key, Operand &&value, UErrorCode &status)
Adds a single option.
Builder & setClose()
Sets this to be an closing markup.
Markup build(UErrorCode &status)
Constructs a new immutable Markup using the name and type and (optionally) options and attributes tha...
Builder & addAttribute(const UnicodeString &key, Operand &&value, UErrorCode &status)
Adds a single attribute.
The Markup class corresponds to the markup nonterminal in the MessageFormat 2 grammar and the markup ...
std::vector< Option > getAttributes() const
Gets the attributes of this markup.
UBool isOpen() const
Checks if this markup is an opening tag.
UBool isClose() const
Checks if this markup is an closing tag.
virtual ~Markup()
Destructor.
std::vector< Option > getOptions() const
Gets the options of this markup.
const UnicodeString & getName() const
Gets the name of this markup.
UBool isStandalone() const
Checks if this markup is an standalone tag.
The Operand class corresponds to the operand nonterminal in the MessageFormat 2 grammar,...
virtual UBool isNull() const
Determines if this operand is the null operand.
const UnicodeString & asVariable() const
Returns a reference to this operand's variable name.
const Literal & asLiteral() const
Returns a reference to this operand's literal contents.
friend void swap(Operand &o1, Operand &o2) noexcept
Non-member swap function.
Operand(const Literal &l)
Literal operand constructor.
UBool isVariable() const
Determines if this operand represents a variable.
UBool isLiteral() const
Determines if this operand represents a literal.
Operand(const UnicodeString &v)
Variable operand constructor.
Operand(const Operand &)
Copy constructor.
virtual Operand & operator=(Operand) noexcept
Assignment operator.
The mutable Operator::Builder class allows the operator to be constructed incrementally.
Builder & setReserved(Reserved &&reserved)
Sets this operator to be a reserved sequence.
Operator build(UErrorCode &status)
Constructs a new immutable Operator using the reserved annotation or the function name and options th...
Builder & setFunctionName(FunctionName &&func)
Sets this operator to be a function annotation and sets its name to func.
Builder & addOption(const UnicodeString &key, Operand &&value, UErrorCode &status) noexcept
Sets this operator to be a function annotation and adds a single option.
Builder(UErrorCode &status)
Default constructor.
The Operator class corresponds to the FunctionRef | Reserved type in the Expression interface defined...
Operator(const Operator &other) noexcept
Copy constructor.
UBool isReserved() const
Determines if this operator is a reserved annotation.
Operator & operator=(Operator) noexcept
Assignment operator.
friend void swap(Operator &o1, Operator &o2) noexcept
Non-member swap function.
const FunctionName & getFunctionName() const
Accesses the function name.
std::vector< Option > getOptions() const
Accesses function options.
const Reserved & asReserved() const
Accesses the underlying reserved sequence.
An Option pairs an option name with an Operand.
const UnicodeString & getName() const
Accesses the left-hand side of the option.
Option & operator=(Option other) noexcept
Assignment operator.
const Operand & getValue() const
Accesses the right-hand side of the option.
Option(const Option &other)
Copy constructor.
virtual ~Option()
Destructor.
Option(const UnicodeString &n, Operand &&r)
Constructor.
friend void swap(Option &o1, Option &o2) noexcept
Non-member swap function.
A PatternPart is a single element (text or expression) in a Pattern.
UBool isExpression() const
Checks if the part is an expression part.
PatternPart(const UnicodeString &t)
Text part constructor.
PatternPart(Expression &&e)
Expression part constructor.
PatternPart & operator=(PatternPart) noexcept
Assignment operator.
PatternPart()=default
Default constructor.
PatternPart(Markup &&m)
Markup part constructor.
UBool isMarkup() const
Checks if the part is a markup part.
UBool isText() const
Checks if the part is a text part.
const Markup & asMarkup() const
Accesses the expression of the part.
const Expression & contents() const
Accesses the expression of the part.
const UnicodeString & asText() const
Accesses the text contents of the part.
PatternPart(const PatternPart &other)
Copy constructor.
friend void swap(PatternPart &p1, PatternPart &p2) noexcept
Non-member swap function.
The mutable Pattern::Builder class allows the pattern to be constructed one part at a time.
Pattern build(UErrorCode &status) const noexcept
Constructs a new immutable Pattern using the list of parts set with previous add() calls.
Builder(UErrorCode &status)
Default constructor.
Builder & add(UnicodeString &&part, UErrorCode &status) noexcept
Adds a single text part to the pattern.
Builder & add(Expression &&part, UErrorCode &status) noexcept
Adds a single expression part to the pattern.
Builder & add(Markup &&part, UErrorCode &status) noexcept
Adds a single markup part to the pattern.
A Pattern is a sequence of formattable parts.
Iterator end() const
Returns a special value to mark the end of iteration.
Pattern & operator=(Pattern) noexcept
Assignment operator.
Pattern(const Pattern &other)
Copy constructor.
friend void swap(Pattern &p1, Pattern &p2) noexcept
Non-member swap function.
Iterator begin() const
Returns the parts of this pattern.
The mutable Reserved::Builder class allows the reserved sequence to be constructed one part at a time...
Reserved build(UErrorCode &status) const noexcept
Constructs a new immutable Reserved using the list of parts set with previous add() calls.
Builder & add(Literal &&part, UErrorCode &status) noexcept
Adds a single literal to the reserved sequence.
Builder(UErrorCode &status)
Default constructor.
The Reserved class represents a reserved annotation, as in the reserved nonterminal in the MessageFor...
Reserved & operator=(Reserved) noexcept
Assignment operator.
const Literal & getPart(int32_t i) const
Indexes into the sequence.
int32_t numParts() const
A Reserved is a sequence of literals.
Reserved(const Reserved &other)
Copy constructor.
friend void swap(Reserved &r1, Reserved &r2) noexcept
Non-member swap function.
The mutable SelectorKeys::Builder class allows the key list to be constructed one key at a time.
Builder & add(Key &&key, UErrorCode &status) noexcept
Adds a single key to the list.
Builder(UErrorCode &status)
Default constructor.
SelectorKeys build(UErrorCode &status) const
Constructs a new immutable SelectorKeys using the list of keys set with previous add() calls.
The SelectorKeys class represents the key list for a single variant.
friend void swap(SelectorKeys &s1, SelectorKeys &s2) noexcept
Non-member swap function.
SelectorKeys & operator=(SelectorKeys other) noexcept
Assignment operator.
bool operator<(const SelectorKeys &other) const
Less than operator.
std::vector< Key > getKeys() const
Returns the underlying list of keys.
SelectorKeys(const SelectorKeys &other)
Copy constructor.
The mutable UnsupportedStatement::Builder class allows the statement to be constructed incrementally.
Builder(UErrorCode &status)
Default constructor.
Builder & setKeyword(const UnicodeString &k)
Sets the keyword of this statement.
Builder & setBody(Reserved &&r)
Sets the body of this statement.
Builder & addExpression(Expression &&e, UErrorCode &status)
Adds an expression to this statement.
UnsupportedStatement build(UErrorCode &status) const
Constructs a new immutable UnsupportedStatement using the keyword, body and (if applicable) expressio...
The UnsupportedStatement class corresponds to the reserved-statement nonterminal in the MessageFormat...
std::vector< Expression > getExpressions() const
Accesses the expressions of this statement.
const Reserved * getBody(UErrorCode &status) const
Accesses the reserved-body of this statement.
const UnicodeString & getKeyword() const
Accesses the keyword of this statement.
UnsupportedStatement & operator=(UnsupportedStatement) noexcept
Assignment operator.
friend void swap(UnsupportedStatement &s1, UnsupportedStatement &s2) noexcept
Non-member swap function.
UnsupportedStatement(const UnsupportedStatement &other)
Copy constructor.
A Variant pairs a list of keys with a pattern It corresponds to the Variant interface defined in http...
Variant(const Variant &)
Copy constructor.
Variant(const SelectorKeys &keys, Pattern &&pattern)
Constructor.
friend void swap(Variant &v1, Variant &v2) noexcept
Non-member swap function.
Variant & operator=(Variant other) noexcept
Assignment operator.
const SelectorKeys & getKeys() const
Accesses the keys of the variant.
Variant()=default
Default constructor.
const Pattern & getPattern() const
Accesses the pattern of the variant.
C++ API: "Smart pointers" for use with and in ICU4C C++ code.
U_EXPORT UBool operator==(const StringPiece &x, const StringPiece &y)
Global operator == for StringPiece.
bool operator!=(const StringPiece &x, const StringPiece &y)
Global operator != for StringPiece.
Definition: stringpiece.h:335
The Pattern::Iterator class provides an iterator over the formattable parts of a pattern.
reference operator*() const
Dereference operator (gets the element at the current iterator position)
Iterator operator++()
Increment operator (advances to the next iterator position)
int8_t UBool
The ICU boolean type, a signed-byte integer.
Definition: umachine.h:247
Basic definitions for ICU, for both C and C++ APIs.
UErrorCode
Standard ICU4C error code type, a substitute for exceptions.
Definition: utypes.h:415
#define U_I18N_API
Set to export library symbols from inside the i18n library, and to import them from outside.
Definition: utypes.h:301