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