private VariableDeclaration generateClassForSoyElement(
      String soyElementClassName, String soyElementAccessorName, TemplateElementNode node) {

    String paramsType = node.getParams().isEmpty() ? "null" : "!" + alias + ".Params";
    String optIjDataType = "!soy.IjData=";

    ImmutableList.Builder<MethodDeclaration> stateMethods = ImmutableList.builder();
    for (TemplateStateVar stateVar : node.getStateVars()) {
      stateMethods.addAll(
          this.generateStateMethodsForSoyElementClass(soyElementClassName, stateVar));
    }
    ImmutableList.Builder<MethodDeclaration> parameterMethods = ImmutableList.builder();
    for (TemplateParam param : node.getParams()) {
      parameterMethods.add(this.generateGetParamMethodForSoyElementClass(param, false));
    }

    ImmutableList.Builder<Statement> stateVarInitializations = ImmutableList.builder();
    for (TemplateStateVar stateVar : node.getStateVars()) {
      JsType jsType = JsType.forIncrementalDomState(stateVar.type());
      JsDoc stateVarJsdoc =
          JsDoc.builder().addParameterizedAnnotation("private", jsType.typeExpr()).build();
      stateVarInitializations.add(
          Statement.assign(
              Expression.THIS.dotAccess(STATE_PREFIX + stateVar.name()),
              translateExpr(stateVar.defaultValue()),
              stateVarJsdoc));
    }
    // Build constructor method.
    Statement ctorBody =
        Statement.of(
            id("super").call(JsRuntime.OPT_DATA, JsRuntime.OPT_IJ_DATA).asStatement(),
            Statement.of(stateVarInitializations.build()));
    MethodDeclaration constructorMethod =
        MethodDeclaration.create(
            "constructor",
            JsDoc.builder()
                .addParam("opt_data", paramsType)
                .addParam("opt_ijData", optIjDataType)
                .build(),
            ctorBody);

    Statement maybeRender =
        Statement.ifStatement(
                id("super")
                    .dotAccess("renderInternal")
                    .call(INCREMENTAL_DOM, JsRuntime.OPT_DATA, id("ignoreSkipHandler")),
                Statement.returnValue(Expression.LITERAL_TRUE))
            .build();

    // Build `renderInternal` method.
    MethodDeclaration renderInternalMethod =
        MethodDeclaration.create(
            "renderInternal",
            JsDoc.builder()
                .addParam(INCREMENTAL_DOM_PARAM_NAME, "!incrementaldomlib.IncrementalDomRenderer")
                .addParam("opt_data", paramsType)
                .addParam("ignoreSkipHandler", "boolean=")
                .addAnnotation("protected")
                .addAnnotation("override")
                .addParameterizedAnnotation("suppress", "checkTypes")
                .build(),
            Statement.of(
                maybeRender,
                // Various parts of the js codegen expects these parameters to be in the local
                // scope.
                VariableDeclaration.builder("opt_ijData")
                    .setRhs(Expression.THIS.dotAccess("ijData"))
                    .build(),
                generateIncrementalDomRenderCalls(node, alias),
                Statement.returnValue(Expression.LITERAL_FALSE)));

    ClassExpression soyElementClass =
        ClassExpression.create(
            SOY_IDOM.dotAccess("$SoyElement"),
            ImmutableList.<MethodDeclaration>builder()
                .add(constructorMethod, renderInternalMethod)
                .addAll(stateMethods.build())
                .addAll(parameterMethods.build())
                .build());
    String elementAccessor = soyElementClassName + "Interface";
    VariableDeclaration classExpression =
        VariableDeclaration.builder(soyElementClassName)
            .setJsDoc(
                JsDoc.builder()
                    .addAnnotation(
                        "extends",
                        "{soyIdom.$SoyElement<" + paramsType + ",!" + elementAccessor + ">}")
                    .addParameterizedAnnotation("implements", soyElementAccessorName)
                    .build())
            .setRhs(soyElementClass)
            .build();
    return classExpression;
  }
private VariableDeclaration generateClassForSoyElement ( String soyElementClassName , String soyElementAccessorName , TemplateElementNode node ) { String paramsType = node . getParams ( ) . isEmpty ( ) ? "null" : "!" + alias + ".Params" ; String optIjDataType = "!soy.IjData=" ; ImmutableList . Builder < MethodDeclaration > stateMethods = ImmutableList . builder ( ) ; for ( TemplateStateVar stateVar : node . getStateVars ( ) ) { stateMethods . addAll ( this . generateStateMethodsForSoyElementClass ( soyElementClassName , stateVar ) ) ; } ImmutableList . Builder < MethodDeclaration > parameterMethods = ImmutableList . builder ( ) ; for ( TemplateParam param : node . getParams ( ) ) { parameterMethods . add ( this . generateGetParamMethodForSoyElementClass ( param , false ) ) ; } ImmutableList . Builder < Statement > stateVarInitializations = ImmutableList . builder ( ) ; for ( TemplateStateVar stateVar : node . getStateVars ( ) ) { JsType jsType = JsType . forIncrementalDomState ( stateVar . type ( ) ) ; JsDoc stateVarJsdoc = JsDoc . builder ( ) . addParameterizedAnnotation ( "private" , jsType . typeExpr ( ) ) . build ( ) ; stateVarInitializations . add ( Statement . assign ( Expression . THIS . dotAccess ( STATE_PREFIX + stateVar . name ( ) ) , translateExpr ( stateVar . defaultValue ( ) ) , stateVarJsdoc ) ) ; } Statement ctorBody = Statement . of ( id ( "super" ) . call ( JsRuntime . OPT_DATA , JsRuntime . OPT_IJ_DATA ) . asStatement ( ) , Statement . of ( stateVarInitializations . build ( ) ) ) ; MethodDeclaration constructorMethod = MethodDeclaration . create ( "constructor" , JsDoc . builder ( ) . addParam ( "opt_data" , paramsType ) . addParam ( "opt_ijData" , optIjDataType ) . build ( ) , ctorBody ) ; Statement maybeRender = Statement . ifStatement ( id ( "super" ) . dotAccess ( "renderInternal" ) . call ( INCREMENTAL_DOM , JsRuntime . OPT_DATA , id ( "ignoreSkipHandler" ) ) , Statement . returnValue ( Expression . LITERAL_TRUE ) ) . build ( ) ; MethodDeclaration renderInternalMethod = MethodDeclaration . create ( "renderInternal" , JsDoc . builder ( ) . addParam ( INCREMENTAL_DOM_PARAM_NAME , "!incrementaldomlib.IncrementalDomRenderer" ) . addParam ( "opt_data" , paramsType ) . addParam ( "ignoreSkipHandler" , "boolean=" ) . addAnnotation ( "protected" ) . addAnnotation ( "override" ) . addParameterizedAnnotation ( "suppress" , "checkTypes" ) . build ( ) , Statement . of ( maybeRender , VariableDeclaration . builder ( "opt_ijData" ) . setRhs ( Expression . THIS . dotAccess ( "ijData" ) ) . build ( ) , generateIncrementalDomRenderCalls ( node , alias ) , Statement . returnValue ( Expression . LITERAL_FALSE ) ) ) ; ClassExpression soyElementClass = ClassExpression . create ( SOY_IDOM . dotAccess ( "$SoyElement" ) , ImmutableList . < MethodDeclaration > builder ( ) . add ( constructorMethod , renderInternalMethod ) . addAll ( stateMethods . build ( ) ) . addAll ( parameterMethods . build ( ) ) . build ( ) ) ; String elementAccessor = soyElementClassName + "Interface" ; VariableDeclaration classExpression = VariableDeclaration . builder ( soyElementClassName ) . setJsDoc ( JsDoc . builder ( ) . addAnnotation ( "extends" , "{soyIdom.$SoyElement<" + paramsType + ",!" + elementAccessor + ">}" ) . addParameterizedAnnotation ( "implements" , soyElementAccessorName ) . build ( ) ) . setRhs ( soyElementClass ) . build ( ) ; return classExpression ; }
Generates class expression for the given template node, provided it is a Soy element.