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);
187  Reserved& operator=(Reserved) noexcept;
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:
243  UnicodeString quoted() const;
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  }
302  Literal& operator=(Literal) noexcept;
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
373 
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
392 
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
661 
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);
802  SelectorKeys& operator=(SelectorKeys other) noexcept;
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
926 template class U_I18N_API LocalPointerBase<message2::data_model::Option>;
927 template class U_I18N_API LocalArray<message2::data_model::Option>;
928 #endif
929 
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
1028 
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); }
1069  const FunctionName& getFunctionName() const;
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:
1127  Builder& setReserved(Reserved&& reserved);
1139  Builder& setFunctionName(FunctionName&& func);
1153  Builder& addOption(const UnicodeString &key, Operand&& value, UErrorCode& status) noexcept;
1171  Operator build(UErrorCode& status);
1181  Builder(UErrorCode& status);
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  }
1220  Operator& operator=(Operator) noexcept;
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
1267 
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);
1458  Markup build(UErrorCode& status);
1468  Builder(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:
1520  UBool isStandaloneAnnotation() const;
1532  UBool isFunctionCall() const;
1543  UBool isReserved() const;
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:
1605  Builder& setOperand(Operand&& rAnd);
1615  Builder& setOperator(Operator&& rAtor);
1627  Builder& addAttribute(const UnicodeString &key, Operand&& value, UErrorCode& status);
1645  Expression build(UErrorCode& status);
1655  Builder(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);
1696  Expression& operator=(Expression) noexcept;
1704  Expression();
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
1750 
1752 namespace message2 {
1753  namespace data_model {
1767  class U_I18N_API UnsupportedStatement : public UObject {
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:
1834  Builder& setKeyword(const UnicodeString& k);
1844  Builder& setBody(Reserved&& r);
1855  Builder& addExpression(Expression&& e, UErrorCode& status);
1871  UnsupportedStatement build(UErrorCode& status) const;
1881  Builder(UErrorCode& status);
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  }
1923  UnsupportedStatement& operator=(UnsupportedStatement) noexcept;
1938  virtual ~UnsupportedStatement();
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);
2050  PatternPart& operator=(PatternPart) noexcept;
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
2111 template class U_I18N_API LocalPointerBase<message2::data_model::PatternPart>;
2112 template class U_I18N_API LocalArray<message2::data_model::PatternPart>;
2113 template class U_I18N_API LocalPointerBase<message2::data_model::UnsupportedStatement>;
2114 template class U_I18N_API LocalArray<message2::data_model::UnsupportedStatement>;
2115 #endif
2116 
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;
2231  Builder(UErrorCode& status);
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);
2281  Pattern& operator=(Pattern) noexcept;
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);
2571  Binding& operator=(Binding) noexcept;
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
2624 
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
2702 
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 
2853  MFDataModel();
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  }
2885  MFDataModel& operator=(MFDataModel) noexcept;
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:
2935  Builder& addBinding(Binding&& b, UErrorCode& status);
2946  Builder& addUnsupportedStatement(UnsupportedStatement&& s, UErrorCode& status);
2958  Builder& addSelector(Expression&& selector, UErrorCode& errorCode) noexcept;
2971  Builder& addVariant(SelectorKeys&& keys, Pattern&& pattern, UErrorCode& errorCode) noexcept;
2983  Builder& setPattern(Pattern&& pattern);
3003  MFDataModel build(UErrorCode& status) const noexcept;
3016  Builder(UErrorCode& status);
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 
friend void swap(SelectorKeys &s1, SelectorKeys &s2) noexcept
Non-member swap function.
UBool isMarkup() const
Checks if the part is a markup part.
A Variant pairs a list of keys with a pattern It corresponds to the Variant interface defined in http...
A PatternPart is a single element (text or expression) in a Pattern.
UBool isExpression() const
Checks if the part is an expression part.
friend void swap(Variant &v1, Variant &v2) noexcept
Non-member swap function.
bool operator!=(const StringPiece &x, const StringPiece &y)
Global operator != for StringPiece.
Definition: stringpiece.h:335
Builder & setClose()
Sets this to be an closing markup.
Variant(const SelectorKeys &keys, Pattern &&pattern)
Constructor.
const VariableName & getVariable() const
Accesses the left-hand side of the binding.
friend void swap(Reserved &r1, Reserved &r2) noexcept
Non-member swap function.
Builder & setName(const UnicodeString &n)
Sets the name of this markup.
UBool isWildcard() const
Determines if this is a wildcard key.
Literal(const Literal &other)
Copy constructor.
T * getAlias() const
Access without ownership change.
Definition: localpointer.h:122
const std::vector< Expression > getSelectors() const
Accesses the selectors.
U_EXPORT UBool operator==(const StringPiece &x, const StringPiece &y)
Global operator == for StringPiece.
friend void swap(Operator &o1, Operator &o2) noexcept
Non-member swap function.
Literal(UBool q, const UnicodeString &s)
Literal constructor.
The UnsupportedStatement class corresponds to the reserved-statement nonterminal in the MessageFormat...
UBool isOpen() const
Checks if this markup is an opening tag.
friend void swap(Literal &l1, Literal &l2) noexcept
Non-member swap function.
const Operand & getValue() const
Accesses the right-hand side of the option.
The mutable Reserved::Builder class allows the reserved sequence to be constructed one part at a time...
std::vector< Variant > getVariants() const
Accesses the variants.
std::vector< Binding > getLocalVariables() const
Accesses the local variable declarations for this data model.
Option(const UnicodeString &n, Operand &&r)
Constructor.
The Literal class corresponds to the literal nonterminal in the MessageFormat 2 grammar, https://github.com/unicode-org/message-format-wg/blob/main/spec/message.abnf and the Literal interface defined in // https://github.com/unicode-org/message-format-wg/blob/main/spec/data-model.md#expressions.
An Option pairs an option name with an Operand.
const UnicodeString & getName() const
Gets the name of this markup.
Iterator operator++()
Increment operator (advances to the next iterator position)
Key(const Literal &lit)
Literal key constructor.
#define U_I18N_API
Set to export library symbols from inside the i18n library, and to import them from outside...
Definition: utypes.h:301
Operand(const Literal &l)
Literal operand constructor.
The Pattern::Iterator class provides an iterator over the formattable parts of a pattern.
friend void swap(Expression &e1, Expression &e2) noexcept
Non-member swap function.
std::vector< Key > getKeys() const
Returns the underlying list of keys.
friend void swap(UnsupportedStatement &s1, UnsupportedStatement &s2) noexcept
Non-member swap function.
The Markup class corresponds to the markup nonterminal in the MessageFormat 2 grammar and the markup ...
&quot;Smart pointer&quot; base class; do not use directly: use LocalPointer etc.
Definition: localpointer.h:68
Key(const Key &other)
Copy constructor.
C++ API: &quot;Smart pointers&quot; for use with and in ICU4C C++ code.
std::vector< UnsupportedStatement > getUnsupportedStatements() const
Accesses the unsupported statements for this data model.
The MFDataModel class describes a parsed representation of the text of a message. ...
UBool isClose() const
Checks if this markup is an closing tag.
friend void swap(Option &o1, Option &o2) noexcept
Non-member swap function.
friend void swap(Binding &b1, Binding &b2) noexcept
Non-member swap function.
UBool isQuoted() const
Determines if this literal appeared as a quoted literal in the message.
&quot;Smart pointer&quot; class, deletes objects via the C++ array delete[] operator.
Definition: localpointer.h:366
const UnicodeString & getName() const
Accesses the left-hand side of the option.
const Pattern & getPattern() const
Accesses the pattern of the variant.
The Operator class corresponds to the FunctionRef | Reserved type in the Expression interface defined...
The Reserved class represents a reserved annotation, as in the reserved nonterminal in the MessageFor...
friend void swap(Key &k1, Key &k2) noexcept
Non-member swap function.
std::vector< Expression > getExpressions() const
Accesses the expressions of this statement.
friend void swap(MFDataModel &m1, MFDataModel &m2) noexcept
Non-member swap function.
PatternPart(Expression &&e)
Expression part constructor.
Iterator end() const
Returns a special value to mark the end of iteration.
const SelectorKeys & getKeys() const
Accesses the keys of the variant.
PatternPart(Markup &&m)
Markup part constructor.
Key()
Wildcard constructor; constructs a Key representing the catchall or wildcard key, &#39;*&#39;...
The Operand class corresponds to the operand nonterminal in the MessageFormat 2 grammar, https://github.com/unicode-org/message-format-wg/blob/main/spec/message.abnf .
Builder & setOpen()
Sets this to be an opening markup.
The Expression class corresponds to the expression nonterminal in the MessageFormat 2 grammar and the...
Binding(const VariableName &v, Expression &&e)
Constructor.
reference operator*() const
Dereference operator (gets the element at the current iterator position)
A Binding pairs a variable name with an expression.
UErrorCode
Standard ICU4C error code type, a substitute for exceptions.
Definition: utypes.h:415
The Key class corresponds to the key nonterminal in the MessageFormat 2 grammar, https://github.com/unicode-org/message-format-wg/blob/main/spec/message.abnf .
Iterator begin() const
Returns the parts of this pattern.
std::vector< Option > getOptions() const
Accesses function options.
Operand(const UnicodeString &v)
Variable operand constructor.
Basic definitions for ICU, for both C and C++ APIs.
A Pattern is a sequence of formattable parts.
UnicodeString is a string class that stores Unicode characters directly and provides similar function...
Definition: unistr.h:295
const UnicodeString & getKeyword() const
Accesses the keyword of this statement.
std::vector< Option > getAttributes() const
Gets the attributes of this markup.
UBool isLocal() const
Returns true if and only if this binding represents a local declaration.
The SelectorKeys class represents the key list for a single variant.
std::vector< Option > getOptions() const
Gets the options of this markup.
friend void swap(PatternPart &p1, PatternPart &p2) noexcept
Non-member swap function.
UBool isStandalone() const
Checks if this markup is an standalone tag.
UObject is the common ICU &quot;boilerplate&quot; class.
Definition: uobject.h:223
std::vector< Option > getAttributes() const
Gets the attributes of this expression.
UMemory is the common ICU base class.
Definition: uobject.h:115
Builder & setStandalone()
Sets this to be a standalone markup.
friend void swap(Operand &o1, Operand &o2) noexcept
Non-member swap function.
UBool isText() const
Checks if the part is a text part.
int8_t UBool
The ICU boolean type, a signed-byte integer.
Definition: umachine.h:247
UBool isReserved() const
Determines if this operator is a reserved annotation.
friend void swap(Pattern &p1, Pattern &p2) noexcept
Non-member swap function.