Files
2026-08-22 08:40:29 +02:00

115 lines
5.0 KiB
JavaScript

"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.hasExtension = exports.clearExtension = exports.setExtension = exports.getExtension = void 0;
const assert_js_1 = require("./private/assert.js");
const extensions_js_1 = require("./private/extensions.js");
/**
* Retrieve an extension value from a message.
*
* The function never returns undefined. Use hasExtension() to check whether an
* extension is set. If the extension is not set, this function returns the
* default value (if one was specified in the protobuf source), or the zero value
* (for example `0` for numeric types, `[]` for repeated extension fields, and
* an empty message instance for message fields).
*
* Extensions are stored as unknown fields on a message. To mutate an extension
* value, make sure to store the new value with setExtension() after mutating.
*
* If the extension does not extend the given message, an error is raised.
*/
function getExtension(message, extension, options) {
assertExtendee(extension, message);
const opt = extension.runtime.bin.makeReadOptions(options);
const ufs = (0, extensions_js_1.filterUnknownFields)(message.getType().runtime.bin.listUnknownFields(message), extension.field);
const [container, get] = (0, extensions_js_1.createExtensionContainer)(extension);
for (const uf of ufs) {
extension.runtime.bin.readField(container, opt.readerFactory(uf.data), extension.field, uf.wireType, opt);
}
return get();
}
exports.getExtension = getExtension;
/**
* Set an extension value on a message. If the message already has a value for
* this extension, the value is replaced.
*
* If the extension does not extend the given message, an error is raised.
*/
function setExtension(message, extension, value, options) {
assertExtendee(extension, message);
const readOpt = extension.runtime.bin.makeReadOptions(options);
const writeOpt = extension.runtime.bin.makeWriteOptions(options);
if (hasExtension(message, extension)) {
const ufs = message
.getType()
.runtime.bin.listUnknownFields(message)
.filter((uf) => uf.no != extension.field.no);
message.getType().runtime.bin.discardUnknownFields(message);
for (const uf of ufs) {
message
.getType()
.runtime.bin.onUnknownField(message, uf.no, uf.wireType, uf.data);
}
}
const writer = writeOpt.writerFactory();
let f = extension.field;
// Implicit presence does not apply to extensions, see https://github.com/protocolbuffers/protobuf/issues/8234
// We patch the field info to use explicit presence:
if (!f.opt && !f.repeated && (f.kind == "enum" || f.kind == "scalar")) {
f = Object.assign(Object.assign({}, extension.field), { opt: true });
}
extension.runtime.bin.writeField(f, value, writer, writeOpt);
const reader = readOpt.readerFactory(writer.finish());
while (reader.pos < reader.len) {
const [no, wireType] = reader.tag();
const data = reader.skip(wireType, no);
message.getType().runtime.bin.onUnknownField(message, no, wireType, data);
}
}
exports.setExtension = setExtension;
/**
* Remove an extension value from a message.
*
* If the extension does not extend the given message, an error is raised.
*/
function clearExtension(message, extension) {
assertExtendee(extension, message);
if (hasExtension(message, extension)) {
const bin = message.getType().runtime.bin;
const ufs = bin
.listUnknownFields(message)
.filter((uf) => uf.no != extension.field.no);
bin.discardUnknownFields(message);
for (const uf of ufs) {
bin.onUnknownField(message, uf.no, uf.wireType, uf.data);
}
}
}
exports.clearExtension = clearExtension;
/**
* Check whether an extension is set on a message.
*/
function hasExtension(message, extension) {
const messageType = message.getType();
return (extension.extendee.typeName === messageType.typeName &&
!!messageType.runtime.bin
.listUnknownFields(message)
.find((uf) => uf.no == extension.field.no));
}
exports.hasExtension = hasExtension;
function assertExtendee(extension, message) {
(0, assert_js_1.assert)(extension.extendee.typeName == message.getType().typeName, `extension ${extension.typeName} can only be applied to message ${extension.extendee.typeName}`);
}