You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
192 lines
7.0 KiB
192 lines
7.0 KiB
2 months ago
|
"use strict";
|
||
|
// Copyright 2021-2024 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.toBinary = toBinary;
|
||
|
exports.writeField = writeField;
|
||
|
const reflect_js_1 = require("./reflect/reflect.js");
|
||
|
const binary_encoding_js_1 = require("./wire/binary-encoding.js");
|
||
|
const descriptors_js_1 = require("./descriptors.js");
|
||
|
// bootstrap-inject google.protobuf.FeatureSet.FieldPresence.LEGACY_REQUIRED: const $name: FeatureSet_FieldPresence.$localName = $number;
|
||
|
const LEGACY_REQUIRED = 3;
|
||
|
// Default options for serializing binary data.
|
||
|
const writeDefaults = {
|
||
|
writeUnknownFields: true,
|
||
|
};
|
||
|
function makeWriteOptions(options) {
|
||
|
return options ? Object.assign(Object.assign({}, writeDefaults), options) : writeDefaults;
|
||
|
}
|
||
|
function toBinary(schema, message, options) {
|
||
|
return writeFields(new binary_encoding_js_1.BinaryWriter(), makeWriteOptions(options), (0, reflect_js_1.reflect)(schema, message)).finish();
|
||
|
}
|
||
|
function writeFields(writer, opts, msg) {
|
||
|
var _a;
|
||
|
for (const f of msg.sortedFields) {
|
||
|
if (!msg.isSet(f)) {
|
||
|
if (f.presence == LEGACY_REQUIRED) {
|
||
|
throw new Error(`cannot encode field ${msg.desc.typeName}.${f.name} to binary: required field not set`);
|
||
|
}
|
||
|
continue;
|
||
|
}
|
||
|
writeField(writer, opts, msg, f);
|
||
|
}
|
||
|
if (opts.writeUnknownFields) {
|
||
|
for (const { no, wireType, data } of (_a = msg.getUnknown()) !== null && _a !== void 0 ? _a : []) {
|
||
|
writer.tag(no, wireType).raw(data);
|
||
|
}
|
||
|
}
|
||
|
return writer;
|
||
|
}
|
||
|
/**
|
||
|
* @private
|
||
|
*/
|
||
|
function writeField(writer, opts, msg, field) {
|
||
|
var _a;
|
||
|
switch (field.fieldKind) {
|
||
|
case "scalar":
|
||
|
case "enum":
|
||
|
writeScalar(writer, (_a = field.scalar) !== null && _a !== void 0 ? _a : descriptors_js_1.ScalarType.INT32, field.number, msg.get(field));
|
||
|
break;
|
||
|
case "list":
|
||
|
writeListField(writer, opts, field, msg.get(field));
|
||
|
break;
|
||
|
case "message":
|
||
|
writeMessageField(writer, opts, field, msg.get(field));
|
||
|
break;
|
||
|
case "map":
|
||
|
for (const [key, val] of msg.get(field)) {
|
||
|
writeMapEntry(writer, opts, field, key, val);
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
function writeScalar(writer, scalarType, fieldNo, value) {
|
||
|
writeScalarValue(writer.tag(fieldNo, writeTypeOfScalar(scalarType)), scalarType, value);
|
||
|
}
|
||
|
function writeMessageField(writer, opts, field, message) {
|
||
|
if (field.delimitedEncoding) {
|
||
|
writeFields(writer.tag(field.number, binary_encoding_js_1.WireType.StartGroup), opts, message).tag(field.number, binary_encoding_js_1.WireType.EndGroup);
|
||
|
}
|
||
|
else {
|
||
|
writeFields(writer.tag(field.number, binary_encoding_js_1.WireType.LengthDelimited).fork(), opts, message).join();
|
||
|
}
|
||
|
}
|
||
|
function writeListField(writer, opts, field, list) {
|
||
|
var _a;
|
||
|
if (field.listKind == "message") {
|
||
|
for (const item of list) {
|
||
|
writeMessageField(writer, opts, field, item);
|
||
|
}
|
||
|
return;
|
||
|
}
|
||
|
const scalarType = (_a = field.scalar) !== null && _a !== void 0 ? _a : descriptors_js_1.ScalarType.INT32;
|
||
|
if (field.packed) {
|
||
|
if (!list.size) {
|
||
|
return;
|
||
|
}
|
||
|
writer.tag(field.number, binary_encoding_js_1.WireType.LengthDelimited).fork();
|
||
|
for (const item of list) {
|
||
|
writeScalarValue(writer, scalarType, item);
|
||
|
}
|
||
|
writer.join();
|
||
|
return;
|
||
|
}
|
||
|
for (const item of list) {
|
||
|
writeScalar(writer, scalarType, field.number, item);
|
||
|
}
|
||
|
}
|
||
|
function writeMapEntry(writer, opts, field, key, value) {
|
||
|
var _a;
|
||
|
writer.tag(field.number, binary_encoding_js_1.WireType.LengthDelimited).fork();
|
||
|
// write key, expecting key field number = 1
|
||
|
writeScalar(writer, field.mapKey, 1, key);
|
||
|
// write value, expecting value field number = 2
|
||
|
switch (field.mapKind) {
|
||
|
case "scalar":
|
||
|
case "enum":
|
||
|
writeScalar(writer, (_a = field.scalar) !== null && _a !== void 0 ? _a : descriptors_js_1.ScalarType.INT32, 2, value);
|
||
|
break;
|
||
|
case "message":
|
||
|
writeFields(writer.tag(2, binary_encoding_js_1.WireType.LengthDelimited).fork(), opts, value).join();
|
||
|
break;
|
||
|
}
|
||
|
writer.join();
|
||
|
}
|
||
|
function writeScalarValue(writer, type, value) {
|
||
|
switch (type) {
|
||
|
case descriptors_js_1.ScalarType.STRING:
|
||
|
writer.string(value);
|
||
|
break;
|
||
|
case descriptors_js_1.ScalarType.BOOL:
|
||
|
writer.bool(value);
|
||
|
break;
|
||
|
case descriptors_js_1.ScalarType.DOUBLE:
|
||
|
writer.double(value);
|
||
|
break;
|
||
|
case descriptors_js_1.ScalarType.FLOAT:
|
||
|
writer.float(value);
|
||
|
break;
|
||
|
case descriptors_js_1.ScalarType.INT32:
|
||
|
writer.int32(value);
|
||
|
break;
|
||
|
case descriptors_js_1.ScalarType.INT64:
|
||
|
writer.int64(value);
|
||
|
break;
|
||
|
case descriptors_js_1.ScalarType.UINT64:
|
||
|
writer.uint64(value);
|
||
|
break;
|
||
|
case descriptors_js_1.ScalarType.FIXED64:
|
||
|
writer.fixed64(value);
|
||
|
break;
|
||
|
case descriptors_js_1.ScalarType.BYTES:
|
||
|
writer.bytes(value);
|
||
|
break;
|
||
|
case descriptors_js_1.ScalarType.FIXED32:
|
||
|
writer.fixed32(value);
|
||
|
break;
|
||
|
case descriptors_js_1.ScalarType.SFIXED32:
|
||
|
writer.sfixed32(value);
|
||
|
break;
|
||
|
case descriptors_js_1.ScalarType.SFIXED64:
|
||
|
writer.sfixed64(value);
|
||
|
break;
|
||
|
case descriptors_js_1.ScalarType.SINT64:
|
||
|
writer.sint64(value);
|
||
|
break;
|
||
|
case descriptors_js_1.ScalarType.UINT32:
|
||
|
writer.uint32(value);
|
||
|
break;
|
||
|
case descriptors_js_1.ScalarType.SINT32:
|
||
|
writer.sint32(value);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
function writeTypeOfScalar(type) {
|
||
|
switch (type) {
|
||
|
case descriptors_js_1.ScalarType.BYTES:
|
||
|
case descriptors_js_1.ScalarType.STRING:
|
||
|
return binary_encoding_js_1.WireType.LengthDelimited;
|
||
|
case descriptors_js_1.ScalarType.DOUBLE:
|
||
|
case descriptors_js_1.ScalarType.FIXED64:
|
||
|
case descriptors_js_1.ScalarType.SFIXED64:
|
||
|
return binary_encoding_js_1.WireType.Bit64;
|
||
|
case descriptors_js_1.ScalarType.FIXED32:
|
||
|
case descriptors_js_1.ScalarType.SFIXED32:
|
||
|
case descriptors_js_1.ScalarType.FLOAT:
|
||
|
return binary_encoding_js_1.WireType.Bit32;
|
||
|
default:
|
||
|
return binary_encoding_js_1.WireType.Varint;
|
||
|
}
|
||
|
}
|