private Statement handleTranslationWithPlaceholders ( MsgNode msg , ImmutableList < SoyPrintDirective > escapingDirectives , Expression soyMsgParts , Expression locale , MsgPartsAndIds partsAndId ) { // We need to render placeholders into a buffer and then pack them into a map to pass to // Runtime.renderSoyMsgWithPlaceholders. Map < String , Function < Expression , Statement > > placeholderNameToPutStatement = new LinkedHashMap <> ( ) ; putPlaceholdersIntoMap ( msg , partsAndId . parts , placeholderNameToPutStatement ) ; // sanity check checkState ( ! placeholderNameToPutStatement . isEmpty ( ) ) ; ConstructorRef cstruct = msg . isPlrselMsg ( ) ? ConstructorRef . PLRSEL_MSG_RENDERER : ConstructorRef . MSG_RENDERER ; Statement initRendererStatement = variables . getCurrentRenderee ( ) . putInstanceField ( thisVar , cstruct . construct ( constant ( partsAndId . id ) , soyMsgParts , locale , constant ( placeholderNameToPutStatement . size ( ) ) ) ) ; List < Statement > initializationStatements = new ArrayList <> ( ) ; initializationStatements . add ( initRendererStatement ) ; for ( Function < Expression , Statement > fn : placeholderNameToPutStatement . values ( ) ) { initializationStatements . add ( fn . apply ( variables . getCurrentRenderee ( ) . accessor ( thisVar ) ) ) ; } Statement initMsgRenderer = Statement . concat ( initializationStatements ) ; Statement render ; if ( areAllPrintDirectivesStreamable ( escapingDirectives ) ) { AppendableAndOptions wrappedAppendable = applyStreamingEscapingDirectives ( escapingDirectives , appendableExpression , parameterLookup . getPluginContext ( ) , variables ) ; FieldRef currentAppendableField = variables . getCurrentAppendable ( ) ; Statement initAppendable = currentAppendableField . putInstanceField ( thisVar , wrappedAppendable . appendable ( ) ) ; Expression appendableExpression = currentAppendableField . accessor ( thisVar ) ; Statement clearAppendable = currentAppendableField . putInstanceField ( thisVar , constantNull ( LOGGING_ADVISING_APPENDABLE_TYPE ) ) ; if ( wrappedAppendable . closeable ( ) ) { clearAppendable = Statement . concat ( appendableExpression . checkedCast ( BytecodeUtils . CLOSEABLE_TYPE ) . invokeVoid ( MethodRef . CLOSEABLE_CLOSE ) , clearAppendable ) ; } render = Statement . concat ( initAppendable , detachState . detachForRender ( variables . getCurrentRenderee ( ) . accessor ( thisVar ) . invoke ( MethodRef . SOY_VALUE_PROVIDER_RENDER_AND_RESOLVE , appendableExpression , // set the isLast field to true since we know this will only be rendered // once. /* isLast=*/ constant ( true ) ) ) , clearAppendable ) ; } else { Label start = new Label ( ) ; SoyExpression value = SoyExpression . forSoyValue ( StringType . getInstance ( ) , detachState . createExpressionDetacher ( start ) . resolveSoyValueProvider ( variables . getCurrentRenderee ( ) . accessor ( thisVar ) ) . checkedCast ( SOY_STRING_TYPE ) ) ; for ( SoyPrintDirective directive : escapingDirectives ) { value = parameterLookup . getRenderContext ( ) . applyPrintDirective ( directive , value ) ; } render = appendableExpression . appendString ( value . unboxAsString ( ) ) . toStatement ( ) . labelStart ( start ) ; } return Statement . concat ( initMsgRenderer , render , // clear the field variables . getCurrentRenderee ( ) . putInstanceField ( thisVar , BytecodeUtils . constantNull ( ConstructorRef . MSG_RENDERER . instanceClass ( ) . type ( ) ) ) ) ; }
Handles a complex message with placeholders .