115 lines
5.0 KiB
JavaScript
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}`);
|
|
}
|