docs: 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;
    }