1*6777b538SAndroid Build Coastguard Worker // Copyright 2015 The Chromium Authors 2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file. 4*6777b538SAndroid Build Coastguard Worker 5*6777b538SAndroid Build Coastguard Worker #ifndef BASE_I18N_MESSAGE_FORMATTER_H_ 6*6777b538SAndroid Build Coastguard Worker #define BASE_I18N_MESSAGE_FORMATTER_H_ 7*6777b538SAndroid Build Coastguard Worker 8*6777b538SAndroid Build Coastguard Worker #include <stdint.h> 9*6777b538SAndroid Build Coastguard Worker 10*6777b538SAndroid Build Coastguard Worker #include <memory> 11*6777b538SAndroid Build Coastguard Worker #include <string> 12*6777b538SAndroid Build Coastguard Worker #include <string_view> 13*6777b538SAndroid Build Coastguard Worker 14*6777b538SAndroid Build Coastguard Worker #include "base/i18n/base_i18n_export.h" 15*6777b538SAndroid Build Coastguard Worker #include "third_party/icu/source/common/unicode/uversion.h" 16*6777b538SAndroid Build Coastguard Worker 17*6777b538SAndroid Build Coastguard Worker U_NAMESPACE_BEGIN 18*6777b538SAndroid Build Coastguard Worker class Formattable; 19*6777b538SAndroid Build Coastguard Worker U_NAMESPACE_END 20*6777b538SAndroid Build Coastguard Worker 21*6777b538SAndroid Build Coastguard Worker namespace base { 22*6777b538SAndroid Build Coastguard Worker 23*6777b538SAndroid Build Coastguard Worker class Time; 24*6777b538SAndroid Build Coastguard Worker 25*6777b538SAndroid Build Coastguard Worker namespace i18n { 26*6777b538SAndroid Build Coastguard Worker 27*6777b538SAndroid Build Coastguard Worker class MessageFormatter; 28*6777b538SAndroid Build Coastguard Worker 29*6777b538SAndroid Build Coastguard Worker namespace internal { 30*6777b538SAndroid Build Coastguard Worker 31*6777b538SAndroid Build Coastguard Worker class BASE_I18N_EXPORT MessageArg { 32*6777b538SAndroid Build Coastguard Worker public: 33*6777b538SAndroid Build Coastguard Worker MessageArg(const char* s); 34*6777b538SAndroid Build Coastguard Worker MessageArg(std::string_view s); 35*6777b538SAndroid Build Coastguard Worker MessageArg(const std::string& s); 36*6777b538SAndroid Build Coastguard Worker MessageArg(const std::u16string& s); 37*6777b538SAndroid Build Coastguard Worker MessageArg(int i); 38*6777b538SAndroid Build Coastguard Worker MessageArg(int64_t i); 39*6777b538SAndroid Build Coastguard Worker MessageArg(double d); 40*6777b538SAndroid Build Coastguard Worker MessageArg(const Time& t); 41*6777b538SAndroid Build Coastguard Worker 42*6777b538SAndroid Build Coastguard Worker MessageArg(const MessageArg&) = delete; 43*6777b538SAndroid Build Coastguard Worker MessageArg& operator=(const MessageArg&) = delete; 44*6777b538SAndroid Build Coastguard Worker 45*6777b538SAndroid Build Coastguard Worker ~MessageArg(); 46*6777b538SAndroid Build Coastguard Worker 47*6777b538SAndroid Build Coastguard Worker private: 48*6777b538SAndroid Build Coastguard Worker friend class base::i18n::MessageFormatter; 49*6777b538SAndroid Build Coastguard Worker MessageArg(); 50*6777b538SAndroid Build Coastguard Worker // Tests if this argument has a value, and if so increments *count. 51*6777b538SAndroid Build Coastguard Worker bool has_value(int* count) const; 52*6777b538SAndroid Build Coastguard Worker std::unique_ptr<icu::Formattable> formattable; 53*6777b538SAndroid Build Coastguard Worker }; 54*6777b538SAndroid Build Coastguard Worker 55*6777b538SAndroid Build Coastguard Worker } // namespace internal 56*6777b538SAndroid Build Coastguard Worker 57*6777b538SAndroid Build Coastguard Worker // Message Formatter with the ICU message format syntax support. 58*6777b538SAndroid Build Coastguard Worker // It can format strings (UTF-8 and UTF-16), numbers and base::Time with 59*6777b538SAndroid Build Coastguard Worker // plural, gender and other 'selectors' support. This is handy if you 60*6777b538SAndroid Build Coastguard Worker // have multiple parameters of differnt types and some of them require 61*6777b538SAndroid Build Coastguard Worker // plural or gender/selector support. 62*6777b538SAndroid Build Coastguard Worker // 63*6777b538SAndroid Build Coastguard Worker // To use this API for locale-sensitive formatting, retrieve a 'message 64*6777b538SAndroid Build Coastguard Worker // template' in the ICU message format from a message bundle (e.g. with 65*6777b538SAndroid Build Coastguard Worker // l10n_util::GetStringUTF16()) and pass it to FormatWith{Named,Numbered}Args. 66*6777b538SAndroid Build Coastguard Worker // 67*6777b538SAndroid Build Coastguard Worker // MessageFormat specs: 68*6777b538SAndroid Build Coastguard Worker // http://icu-project.org/apiref/icu4j/com/ibm/icu/text/MessageFormat.html 69*6777b538SAndroid Build Coastguard Worker // http://icu-project.org/apiref/icu4c/classicu_1_1DecimalFormat.html#details 70*6777b538SAndroid Build Coastguard Worker // Examples: 71*6777b538SAndroid Build Coastguard Worker // http://userguide.icu-project.org/formatparse/messages 72*6777b538SAndroid Build Coastguard Worker // message_formatter_unittest.cc 73*6777b538SAndroid Build Coastguard Worker // go/plurals inside Google. 74*6777b538SAndroid Build Coastguard Worker // TODO(jshin): Document this API in md format docs. 75*6777b538SAndroid Build Coastguard Worker // Caveat: 76*6777b538SAndroid Build Coastguard Worker // When plural/select/gender is used along with other format specifiers such 77*6777b538SAndroid Build Coastguard Worker // as date or number, plural/select/gender should be at the top level. It's 78*6777b538SAndroid Build Coastguard Worker // not an ICU restriction but a constraint imposed by Google's translation 79*6777b538SAndroid Build Coastguard Worker // infrastructure. Message A does not work. It must be revised to Message B. 80*6777b538SAndroid Build Coastguard Worker // 81*6777b538SAndroid Build Coastguard Worker // A. 82*6777b538SAndroid Build Coastguard Worker // Rated <ph name="RATING">{0, number,0.0}<ex>3.2</ex></ph> 83*6777b538SAndroid Build Coastguard Worker // by {1, plural, =1{a user} other{# users}} 84*6777b538SAndroid Build Coastguard Worker // 85*6777b538SAndroid Build Coastguard Worker // B. 86*6777b538SAndroid Build Coastguard Worker // {1, plural, 87*6777b538SAndroid Build Coastguard Worker // =1{Rated <ph name="RATING">{0, number,0.0}<ex>3.2</ex></ph> 88*6777b538SAndroid Build Coastguard Worker // by a user.} 89*6777b538SAndroid Build Coastguard Worker // other{Rated <ph name="RATING">{0, number,0.0}<ex>3.2</ex></ph> 90*6777b538SAndroid Build Coastguard Worker // by # users.}} 91*6777b538SAndroid Build Coastguard Worker 92*6777b538SAndroid Build Coastguard Worker class BASE_I18N_EXPORT MessageFormatter { 93*6777b538SAndroid Build Coastguard Worker public: 94*6777b538SAndroid Build Coastguard Worker MessageFormatter() = delete; 95*6777b538SAndroid Build Coastguard Worker MessageFormatter(const MessageFormatter&) = delete; 96*6777b538SAndroid Build Coastguard Worker MessageFormatter& operator=(const MessageFormatter&) = delete; 97*6777b538SAndroid Build Coastguard Worker 98*6777b538SAndroid Build Coastguard Worker static std::u16string FormatWithNamedArgs( 99*6777b538SAndroid Build Coastguard Worker std::u16string_view msg, 100*6777b538SAndroid Build Coastguard Worker std::string_view name0 = std::string_view(), 101*6777b538SAndroid Build Coastguard Worker const internal::MessageArg& arg0 = internal::MessageArg(), 102*6777b538SAndroid Build Coastguard Worker std::string_view name1 = std::string_view(), 103*6777b538SAndroid Build Coastguard Worker const internal::MessageArg& arg1 = internal::MessageArg(), 104*6777b538SAndroid Build Coastguard Worker std::string_view name2 = std::string_view(), 105*6777b538SAndroid Build Coastguard Worker const internal::MessageArg& arg2 = internal::MessageArg(), 106*6777b538SAndroid Build Coastguard Worker std::string_view name3 = std::string_view(), 107*6777b538SAndroid Build Coastguard Worker const internal::MessageArg& arg3 = internal::MessageArg(), 108*6777b538SAndroid Build Coastguard Worker std::string_view name4 = std::string_view(), 109*6777b538SAndroid Build Coastguard Worker const internal::MessageArg& arg4 = internal::MessageArg(), 110*6777b538SAndroid Build Coastguard Worker std::string_view name5 = std::string_view(), 111*6777b538SAndroid Build Coastguard Worker const internal::MessageArg& arg5 = internal::MessageArg(), 112*6777b538SAndroid Build Coastguard Worker std::string_view name6 = std::string_view(), 113*6777b538SAndroid Build Coastguard Worker const internal::MessageArg& arg6 = internal::MessageArg()); 114*6777b538SAndroid Build Coastguard Worker 115*6777b538SAndroid Build Coastguard Worker static std::u16string FormatWithNumberedArgs( 116*6777b538SAndroid Build Coastguard Worker std::u16string_view msg, 117*6777b538SAndroid Build Coastguard Worker const internal::MessageArg& arg0 = internal::MessageArg(), 118*6777b538SAndroid Build Coastguard Worker const internal::MessageArg& arg1 = internal::MessageArg(), 119*6777b538SAndroid Build Coastguard Worker const internal::MessageArg& arg2 = internal::MessageArg(), 120*6777b538SAndroid Build Coastguard Worker const internal::MessageArg& arg3 = internal::MessageArg(), 121*6777b538SAndroid Build Coastguard Worker const internal::MessageArg& arg4 = internal::MessageArg(), 122*6777b538SAndroid Build Coastguard Worker const internal::MessageArg& arg5 = internal::MessageArg(), 123*6777b538SAndroid Build Coastguard Worker const internal::MessageArg& arg6 = internal::MessageArg()); 124*6777b538SAndroid Build Coastguard Worker }; 125*6777b538SAndroid Build Coastguard Worker 126*6777b538SAndroid Build Coastguard Worker } // namespace i18n 127*6777b538SAndroid Build Coastguard Worker } // namespace base 128*6777b538SAndroid Build Coastguard Worker 129*6777b538SAndroid Build Coastguard Worker #endif // BASE_I18N_MESSAGE_FORMATTER_H_ 130