@@ -243,7 +243,7 @@ void TestMessageFormat2::testCustomFunctions() {
243243 testCustomFunctionsComplexMessage (errorCode);
244244 testGrammarCasesFormatter (errorCode);
245245 testListFormatter (errorCode);
246- // testMessageRefFormatter(errorCode);
246+ testMessageRefFormatter (errorCode);
247247 testComplexOptions (errorCode);
248248}
249249
@@ -644,7 +644,6 @@ void TestMessageFormat2::testListFormatter(IcuTestErrorCode& errorCode) {
644644 See ICU4J: CustomFormatterMessageRefTest.java
645645*/
646646
647- #if false
648647/* static */ Hashtable* message2::ResourceManager::properties (UErrorCode& errorCode) {
649648 NULL_ON_ERROR (errorCode);
650649
@@ -678,47 +677,54 @@ void TestMessageFormat2::testListFormatter(IcuTestErrorCode& errorCode) {
678677 return nullptr ;
679678}
680679
681- Formatter* ResourceManagerFactory::createFormatter (const Locale& locale, UErrorCode& errorCode) {
682- if (U_FAILURE (errorCode)) {
683- return nullptr ;
684- }
685-
686- Formatter* result = new ResourceManager (locale);
687- if (result == nullptr ) {
688- errorCode = U_MEMORY_ALLOCATION_ERROR;
689- }
690- return result;
691- }
692-
693680using Arguments = MessageArguments;
694681
695- // TODO: The next test is commented out because we need to write code
696- // to convert an options map to a MessageArguments (mapping FormattedPlaceholder
697- // back to Formattable)
698-
699682static Arguments localToGlobal (const FunctionOptionsMap& opts, UErrorCode& status) {
700683 if (U_FAILURE (status)) {
701684 return {};
702685 }
703686 std::map<UnicodeString, message2::Formattable> result;
704687 for (auto iter = opts.cbegin (); iter != opts.cend (); ++iter) {
705- result[iter->first ] = iter->second ->getSource (status );
688+ result[iter->first ] = iter->second ->getOperand ( );
706689 }
707690 return MessageArguments (result, status);
708691}
709692
710- message2::FormattedPlaceholder ResourceManager::format (FormattedPlaceholder&& arg, FunctionOptions&& options, UErrorCode& errorCode) const {
693+ FunctionValue* ResourceManager::call (const FunctionContext&,
694+ FunctionValue& arg,
695+ FunctionOptions&& options,
696+ UErrorCode& errorCode) {
697+ NULL_ON_ERROR (errorCode);
698+
699+ LocalPointer<ResourceManagerValue>
700+ result (new ResourceManagerValue (arg, std::move (options), errorCode));
701+
702+ if (U_SUCCESS (errorCode) && !result.isValid ()) {
703+ errorCode = U_MEMORY_ALLOCATION_ERROR;
704+ return nullptr ;
705+ }
706+ return result.orphan ();
707+ }
708+
709+ UnicodeString message2::ResourceManagerValue::formatToString (UErrorCode&) const {
710+ return formattedString;
711+ }
712+
713+ message2::ResourceManagerValue::ResourceManagerValue (FunctionValue& arg,
714+ FunctionOptions&& options,
715+ UErrorCode& errorCode) {
711716 if (U_FAILURE (errorCode)) {
712- return {} ;
717+ return ;
713718 }
714719
715- message2::FormattedPlaceholder errorVal = message2::FormattedPlaceholder (" msgref" );
720+ operand = arg.getOperand ();
721+ opts = std::move (options); // Tests don't cover composition, so no need to merge options
716722
717- const Formattable* toFormat = arg. getSource (errorCode) ;
723+ const Formattable* toFormat = &operand ;
718724 // Check for null or fallback
719725 if (errorCode == U_ILLEGAL_ARGUMENT_ERROR) {
720726 errorCode = U_MF_FORMATTING_ERROR;
721- return errorVal ;
727+ return ;
722728 }
723729 UnicodeString in;
724730 switch (toFormat->getType ()) {
@@ -728,30 +734,33 @@ message2::FormattedPlaceholder ResourceManager::format(FormattedPlaceholder&& ar
728734 }
729735 default : {
730736 // Ignore non-strings
731- return errorVal ;
737+ return ;
732738 }
733739 }
734- FunctionOptionsMap opt = FunctionOptions::getOptions (std::move (options));
735- bool hasProperties = opt.count (" resbundle" ) > 0 && opt[" resbundle" ].getValue ().getType () == UFMT_OBJECT && opt[" resbundle" ].getValue ().getObject (errorCode)->tag () == u" properties" ;
740+ FunctionOptionsMap opt = opts.getOptions ();
741+ bool hasProperties = opt.count (" resbundle" ) > 0
742+ && opt[" resbundle" ]->getOperand ().getType () == UFMT_OBJECT
743+ && opt[" resbundle" ]->getOperand ().getObject (errorCode)->tag () == u" properties" ;
736744
737745 // If properties were provided, look up the given string in the properties,
738746 // yielding a message
739747 if (hasProperties) {
740- const FormattableProperties* properties = reinterpret_cast <const FormattableProperties*>(opt[" resbundle" ].getValue ().getObject (errorCode));
748+ const FormattableProperties* properties = reinterpret_cast <const FormattableProperties*>
749+ (opt[" resbundle" ]->getOperand ().getObject (errorCode));
741750 U_ASSERT (U_SUCCESS (errorCode));
742751 UnicodeString* msg = static_cast <UnicodeString*>(properties->properties ->get (in));
743752 if (msg == nullptr ) {
744753 // No message given for this key -- error out
745754 errorCode = U_MF_FORMATTING_ERROR;
746- return errorVal ;
755+ return ;
747756 }
748757 MessageFormatter::Builder mfBuilder (errorCode);
749758 UParseError parseErr;
750759 // Any parse/data model errors will be propagated
751760 MessageFormatter mf = mfBuilder.setPattern (*msg, parseErr, errorCode).build (errorCode);
752761 Arguments arguments = localToGlobal (opt, errorCode);
753762 if (U_FAILURE (errorCode)) {
754- return errorVal ;
763+ return ;
755764 }
756765
757766 UErrorCode savedStatus = errorCode;
@@ -762,14 +771,16 @@ message2::FormattedPlaceholder ResourceManager::format(FormattedPlaceholder&& ar
762771 if (U_FAILURE (errorCode)) {
763772 errorCode = savedStatus;
764773 }
765- return arg. withOutput ( FormattedValue ( std::move (result)), errorCode) ;
774+ formattedString = result ;
766775 } else {
767776 // Properties must be provided
768777 errorCode = U_MF_FORMATTING_ERROR;
769778 }
770- return errorVal ;
779+ return ;
771780}
772781
782+ ResourceManager::~ResourceManager () {}
783+ ResourceManagerValue::~ResourceManagerValue () {}
773784
774785void TestMessageFormat2::testMessageRefFormatter (IcuTestErrorCode& errorCode) {
775786 CHECK_ERROR (errorCode);
@@ -782,7 +793,7 @@ void TestMessageFormat2::testMessageRefFormatter(IcuTestErrorCode& errorCode) {
782793 return ;
783794 }
784795 MFFunctionRegistry reg = MFFunctionRegistry::Builder (errorCode)
785- .adoptFormatter (FunctionName (" msgRef" ), new ResourceManagerFactory (), errorCode)
796+ .adoptFunction (FunctionName (" msgRef" ), new ResourceManager (), errorCode)
786797 .build ();
787798 CHECK_ERROR (errorCode);
788799
@@ -842,7 +853,6 @@ void TestMessageFormat2::testMessageRefFormatter(IcuTestErrorCode& errorCode) {
842853 .build ();
843854 TestUtils::runTestCase (*this , test, errorCode);
844855}
845- #endif
846856
847857FunctionValue* NounFunction::call (const FunctionContext&,
848858 FunctionValue& arg,
0 commit comments