"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ModuleVisitor = void 0;
const ast_1 = require("@wapc/widl/ast");
const helpers_1 = require("./helpers");
const class_visitor_1 = require("./class_visitor");
const host_visitor_1 = require("./host_visitor");
const handlers_visitor_1 = require("./handlers_visitor");
const wrappers_visitor_1 = require("./wrappers_visitor");
const builder_visitor_1 = require("./builder_visitor");
class ModuleVisitor extends class_visitor_1.ClassVisitor {
    constructor(writer) {
        super(writer);
        this.setCallback("AllOperationsBefore", "host", (context) => {
            const host = new host_visitor_1.HostVisitor(writer);
            context.document.accept(context, host);
        });
        this.setCallback("AllOperationsBefore", "handlers", (context) => {
            const handlers = new handlers_visitor_1.HandlersVisitor(this.writer);
            context.document.accept(context, handlers);
        });
        this.setCallback("AllOperationsBefore", "wrappers", (context) => {
            const wrappers = new wrappers_visitor_1.WrappersVisitor(this.writer);
            context.document.accept(context, wrappers);
        });
    }
    visitDocumentBefore(context) {
        this.write(`import { Decoder, Writer, Encoder, Sizer, Codec } from "@wapc/as-msgpack";\n\n`);
        super.triggerDocumentBefore(context);
    }
    visitInterface(context) {
        this.write(`\n`);
        super.triggerInterface(context);
    }
    visitOperation(context) {
        if (context.operation.isUnary()) {
            return;
        }
        const argObject = this.convertOperationToObject(context.operation);
        const args = new class_visitor_1.ClassVisitor(this.writer);
        argObject.accept(context.clone({ object: argObject }), args);
        super.triggerOperation(context);
    }
    convertOperationToObject(operation) {
        var fields = operation.arguments.map((arg) => {
            return new ast_1.FieldDefinition(arg.loc, arg.name, arg.description, arg.type, arg.default, arg.annotations);
        });
        return new ast_1.ObjectDefinition(operation.loc, new ast_1.Name(operation.name.loc, helpers_1.capitalize(operation.name.value) + "Args"), undefined, [], operation.annotations, fields);
    }
    visitObjectFieldsAfter(context) {
        var object = context.object;
        super.visitObjectFieldsAfter(context);
        this.write(`\n`);
        this.write(`  static newBuilder(): ${object.name.value}Builder {
      return new ${object.name.value}Builder();
    }\n`);
        super.triggerObjectFieldsAfter(context);
    }
    visitObjectAfter(context) {
        this.write(`}\n\n`);
        const builder = new builder_visitor_1.BuilderVisitor(this.writer);
        context.object.accept(context, builder);
        super.triggerObjectAfter(context);
    }
}
exports.ModuleVisitor = ModuleVisitor;
//# sourceMappingURL=module_visitor.js.map