"use strict";
// Copyright 2021-2023 Buf Technologies, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
Object.defineProperty(exports, "__esModule", { value: true });
exports.makeBinaryFormatProto3 = void 0;
const field_js_1 = require("../field.js");
const binary_format_common_js_1 = require("./binary-format-common.js");
/* eslint-disable @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unnecessary-condition, @typescript-eslint/strict-boolean-expressions, prefer-const, no-case-declarations */
function makeBinaryFormatProto3() {
    return Object.assign(Object.assign({}, (0, binary_format_common_js_1.makeBinaryFormatCommon)()), { writeMessage(message, writer, options) {
            const type = message.getType();
            for (const field of type.fields.byNumber()) {
                let value, // this will be our field value, whether it is member of a oneof or regular field
                repeated = field.repeated, localName = field.localName;
                if (field.oneof) {
                    const oneof = message[field.oneof.localName];
                    if (oneof.case !== localName) {
                        continue; // field is not selected, skip
                    }
                    value = oneof.value;
                }
                else {
                    value = message[localName];
                }
                switch (field.kind) {
                    case "scalar":
                    case "enum":
                        let scalarType = field.kind == "enum" ? field_js_1.ScalarType.INT32 : field.T;
                        if (repeated) {
                            if (field.packed) {
                                (0, binary_format_common_js_1.writePacked)(writer, scalarType, field.no, value);
                            }
                            else {
                                for (const item of value) {
                                    (0, binary_format_common_js_1.writeScalar)(writer, scalarType, field.no, item, true);
                                }
                            }
                        }
                        else {
                            if (value !== undefined) {
                                (0, binary_format_common_js_1.writeScalar)(writer, scalarType, field.no, value, !!field.oneof || field.opt);
                            }
                        }
                        break;
                    case "message":
                        if (repeated) {
                            for (const item of value) {
                                (0, binary_format_common_js_1.writeMessageField)(writer, options, field.T, field.no, item);
                            }
                        }
                        else {
                            (0, binary_format_common_js_1.writeMessageField)(writer, options, field.T, field.no, value);
                        }
                        break;
                    case "map":
                        for (const [key, val] of Object.entries(value)) {
                            (0, binary_format_common_js_1.writeMapEntry)(writer, options, field, key, val);
                        }
                        break;
                }
            }
            if (options.writeUnknownFields) {
                this.writeUnknownFields(message, writer);
            }
            return writer;
        } });
}
exports.makeBinaryFormatProto3 = makeBinaryFormatProto3;
