code: private void generateConstructor(
        ImmutableMap<TemplateParam, SoyExpression> defaultParamInitializers) {
      final Label start = new Label();
      final Label end = new Label();
      final LocalVariable thisVar = createThisVar(template.typeInfo(), start, end);
      final LocalVariable paramsVar = createLocal("params", 1, SOY_RECORD_TYPE, start, end);
      final LocalVariable ijVar = createLocal("ij", 2, SOY_RECORD_TYPE, start, end);
      final List<Statement> assignments = new ArrayList<>();
      assignments.add(paramsField.putInstanceField(thisVar, paramsVar));
      assignments.add(ijField.putInstanceField(thisVar, ijVar));
      for (TemplateParam param : templateNode.getAllParams()) {
        Expression paramProvider =
            getParam(paramsVar, ijVar, param, defaultParamInitializers.get(param));
        assignments.add(paramFields.get(param.name()).putInstanceField(thisVar, paramProvider));
      }
      Statement constructorBody =
          new Statement() {
            @Override
            protected void doGen(CodeBuilder ga) {
              ga.mark(start);
              // call super()
              thisVar.gen(ga);
              ga.invokeConstructor(OBJECT.type(), NULLARY_INIT);
              for (Statement assignment : assignments) {
                assignment.gen(ga);
              }
              ga.visitInsn(Opcodes.RETURN);
              ga.visitLabel(end);
              thisVar.tableEntry(ga);
              paramsVar.tableEntry(ga);
              ijVar.tableEntry(ga);
            }
          };
      constructorBody.writeMethod(Opcodes.ACC_PUBLIC, template.constructor().method(), writer);
    }
docs: Generate a public constructor that assigns our final field and checks for missing required
  params.
  
  <p>This constructor is called by the generate factory classes.