@@ -240,7 +240,7 @@ void TestMessageFormat2::testCustomFunctions() {
240240 testCustomFunctionsComplexMessage (errorCode);
241241 testGrammarCasesFormatter (errorCode);
242242 testListFormatter (errorCode);
243- // testMessageRefFormatter(errorCode);
243+ testMessageRefFormatter (errorCode);
244244 testComplexOptions (errorCode);
245245}
246246
@@ -641,7 +641,6 @@ void TestMessageFormat2::testListFormatter(IcuTestErrorCode& errorCode) {
641641 See ICU4J: CustomFormatterMessageRefTest.java
642642*/
643643
644- #if false
645644/* static */ Hashtable* message2::ResourceManager::properties (UErrorCode& errorCode) {
646645 NULL_ON_ERROR (errorCode);
647646
@@ -675,47 +674,54 @@ void TestMessageFormat2::testListFormatter(IcuTestErrorCode& errorCode) {
675674 return nullptr ;
676675}
677676
678- Formatter* ResourceManagerFactory::createFormatter (const Locale& locale, UErrorCode& errorCode) {
679- if (U_FAILURE (errorCode)) {
680- return nullptr ;
681- }
682-
683- Formatter* result = new ResourceManager (locale);
684- if (result == nullptr ) {
685- errorCode = U_MEMORY_ALLOCATION_ERROR;
686- }
687- return result;
688- }
689-
690677using Arguments = MessageArguments;
691678
692- // TODO: The next test is commented out because we need to write code
693- // to convert an options map to a MessageArguments (mapping FormattedPlaceholder
694- // back to Formattable)
695-
696679static Arguments localToGlobal (const FunctionOptionsMap& opts, UErrorCode& status) {
697680 if (U_FAILURE (status)) {
698681 return {};
699682 }
700683 std::map<UnicodeString, message2::Formattable> result;
701684 for (auto iter = opts.cbegin (); iter != opts.cend (); ++iter) {
702- result[iter->first ] = iter->second ->getSource (status );
685+ result[iter->first ] = iter->second ->getOperand ( );
703686 }
704687 return MessageArguments (result, status);
705688}
706689
707- message2::FormattedPlaceholder ResourceManager::format (FormattedPlaceholder&& arg, FunctionOptions&& options, UErrorCode& errorCode) const {
690+ FunctionValue* ResourceManager::call (const FunctionContext&,
691+ FunctionValue& arg,
692+ FunctionOptions&& options,
693+ UErrorCode& errorCode) {
694+ NULL_ON_ERROR (errorCode);
695+
696+ LocalPointer<ResourceManagerValue>
697+ result (new ResourceManagerValue (arg, std::move (options), errorCode));
698+
699+ if (U_SUCCESS (errorCode) && !result.isValid ()) {
700+ errorCode = U_MEMORY_ALLOCATION_ERROR;
701+ return nullptr ;
702+ }
703+ return result.orphan ();
704+ }
705+
706+ UnicodeString message2::ResourceManagerValue::formatToString (UErrorCode&) const {
707+ return formattedString;
708+ }
709+
710+ message2::ResourceManagerValue::ResourceManagerValue (FunctionValue& arg,
711+ FunctionOptions&& options,
712+ UErrorCode& errorCode) {
708713 if (U_FAILURE (errorCode)) {
709- return {} ;
714+ return ;
710715 }
711716
712- message2::FormattedPlaceholder errorVal = message2::FormattedPlaceholder (" msgref" );
717+ operand = arg.getOperand ();
718+ opts = std::move (options); // Tests don't cover composition, so no need to merge options
713719
714- const Formattable* toFormat = arg. getSource (errorCode) ;
720+ const Formattable* toFormat = &operand ;
715721 // Check for null or fallback
716722 if (errorCode == U_ILLEGAL_ARGUMENT_ERROR) {
717723 errorCode = U_MF_FORMATTING_ERROR;
718- return errorVal ;
724+ return ;
719725 }
720726 UnicodeString in;
721727 switch (toFormat->getType ()) {
@@ -725,30 +731,33 @@ message2::FormattedPlaceholder ResourceManager::format(FormattedPlaceholder&& ar
725731 }
726732 default : {
727733 // Ignore non-strings
728- return errorVal ;
734+ return ;
729735 }
730736 }
731- FunctionOptionsMap opt = FunctionOptions::getOptions (std::move (options));
732- bool hasProperties = opt.count (" resbundle" ) > 0 && opt[" resbundle" ].getValue ().getType () == UFMT_OBJECT && opt[" resbundle" ].getValue ().getObject (errorCode)->tag () == u" properties" ;
737+ FunctionOptionsMap opt = opts.getOptions ();
738+ bool hasProperties = opt.count (" resbundle" ) > 0
739+ && opt[" resbundle" ]->getOperand ().getType () == UFMT_OBJECT
740+ && opt[" resbundle" ]->getOperand ().getObject (errorCode)->tag () == u" properties" ;
733741
734742 // If properties were provided, look up the given string in the properties,
735743 // yielding a message
736744 if (hasProperties) {
737- const FormattableProperties* properties = reinterpret_cast <const FormattableProperties*>(opt[" resbundle" ].getValue ().getObject (errorCode));
745+ const FormattableProperties* properties = reinterpret_cast <const FormattableProperties*>
746+ (opt[" resbundle" ]->getOperand ().getObject (errorCode));
738747 U_ASSERT (U_SUCCESS (errorCode));
739748 UnicodeString* msg = static_cast <UnicodeString*>(properties->properties ->get (in));
740749 if (msg == nullptr ) {
741750 // No message given for this key -- error out
742751 errorCode = U_MF_FORMATTING_ERROR;
743- return errorVal ;
752+ return ;
744753 }
745754 MessageFormatter::Builder mfBuilder (errorCode);
746755 UParseError parseErr;
747756 // Any parse/data model errors will be propagated
748757 MessageFormatter mf = mfBuilder.setPattern (*msg, parseErr, errorCode).build (errorCode);
749758 Arguments arguments = localToGlobal (opt, errorCode);
750759 if (U_FAILURE (errorCode)) {
751- return errorVal ;
760+ return ;
752761 }
753762
754763 UErrorCode savedStatus = errorCode;
@@ -759,14 +768,16 @@ message2::FormattedPlaceholder ResourceManager::format(FormattedPlaceholder&& ar
759768 if (U_FAILURE (errorCode)) {
760769 errorCode = savedStatus;
761770 }
762- return arg. withOutput ( FormattedValue ( std::move (result)), errorCode) ;
771+ formattedString = result ;
763772 } else {
764773 // Properties must be provided
765774 errorCode = U_MF_FORMATTING_ERROR;
766775 }
767- return errorVal ;
776+ return ;
768777}
769778
779+ ResourceManager::~ResourceManager () {}
780+ ResourceManagerValue::~ResourceManagerValue () {}
770781
771782void TestMessageFormat2::testMessageRefFormatter (IcuTestErrorCode& errorCode) {
772783 CHECK_ERROR (errorCode);
@@ -779,7 +790,7 @@ void TestMessageFormat2::testMessageRefFormatter(IcuTestErrorCode& errorCode) {
779790 return ;
780791 }
781792 MFFunctionRegistry reg = MFFunctionRegistry::Builder (errorCode)
782- .adoptFormatter (FunctionName (" msgRef" ), new ResourceManagerFactory (), errorCode)
793+ .adoptFunction (FunctionName (" msgRef" ), new ResourceManager (), errorCode)
783794 .build ();
784795 CHECK_ERROR (errorCode);
785796
@@ -839,7 +850,6 @@ void TestMessageFormat2::testMessageRefFormatter(IcuTestErrorCode& errorCode) {
839850 .build ();
840851 TestUtils::runTestCase (*this , test, errorCode);
841852}
842- #endif
843853
844854FunctionValue* NounFunction::call (const FunctionContext&,
845855 FunctionValue& arg,
0 commit comments