Erster Commit
This commit is contained in:
+16
@@ -0,0 +1,16 @@
|
||||
/**
|
||||
* Assert that condition is truthy or throw error (with message)
|
||||
*/
|
||||
export declare function assert(condition: unknown, msg?: string): asserts condition;
|
||||
/**
|
||||
* Assert a valid signed protobuf 32-bit integer.
|
||||
*/
|
||||
export declare function assertInt32(arg: unknown): asserts arg is number;
|
||||
/**
|
||||
* Assert a valid unsigned protobuf 32-bit integer.
|
||||
*/
|
||||
export declare function assertUInt32(arg: unknown): asserts arg is number;
|
||||
/**
|
||||
* Assert a valid protobuf float value.
|
||||
*/
|
||||
export declare function assertFloat32(arg: unknown): asserts arg is number;
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
"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.assertFloat32 = exports.assertUInt32 = exports.assertInt32 = exports.assert = void 0;
|
||||
/**
|
||||
* Assert that condition is truthy or throw error (with message)
|
||||
*/
|
||||
function assert(condition, msg) {
|
||||
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions -- we want the implicit conversion to boolean
|
||||
if (!condition) {
|
||||
throw new Error(msg);
|
||||
}
|
||||
}
|
||||
exports.assert = assert;
|
||||
const FLOAT32_MAX = 3.4028234663852886e38, FLOAT32_MIN = -3.4028234663852886e38, UINT32_MAX = 0xffffffff, INT32_MAX = 0x7fffffff, INT32_MIN = -0x80000000;
|
||||
/**
|
||||
* Assert a valid signed protobuf 32-bit integer.
|
||||
*/
|
||||
function assertInt32(arg) {
|
||||
if (typeof arg !== "number")
|
||||
throw new Error("invalid int 32: " + typeof arg);
|
||||
if (!Number.isInteger(arg) || arg > INT32_MAX || arg < INT32_MIN)
|
||||
throw new Error("invalid int 32: " + arg); // eslint-disable-line @typescript-eslint/restrict-plus-operands -- we want the implicit conversion to string
|
||||
}
|
||||
exports.assertInt32 = assertInt32;
|
||||
/**
|
||||
* Assert a valid unsigned protobuf 32-bit integer.
|
||||
*/
|
||||
function assertUInt32(arg) {
|
||||
if (typeof arg !== "number")
|
||||
throw new Error("invalid uint 32: " + typeof arg);
|
||||
if (!Number.isInteger(arg) || arg > UINT32_MAX || arg < 0)
|
||||
throw new Error("invalid uint 32: " + arg); // eslint-disable-line @typescript-eslint/restrict-plus-operands -- we want the implicit conversion to string
|
||||
}
|
||||
exports.assertUInt32 = assertUInt32;
|
||||
/**
|
||||
* Assert a valid protobuf float value.
|
||||
*/
|
||||
function assertFloat32(arg) {
|
||||
if (typeof arg !== "number")
|
||||
throw new Error("invalid float 32: " + typeof arg);
|
||||
if (!Number.isFinite(arg))
|
||||
return;
|
||||
if (arg > FLOAT32_MAX || arg < FLOAT32_MIN)
|
||||
throw new Error("invalid float 32: " + arg); // eslint-disable-line @typescript-eslint/restrict-plus-operands -- we want the implicit conversion to string
|
||||
}
|
||||
exports.assertFloat32 = assertFloat32;
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
import type { IBinaryWriter } from "../binary-encoding.js";
|
||||
import type { BinaryFormat, BinaryWriteOptions } from "../binary-format.js";
|
||||
import type { FieldInfo } from "../field.js";
|
||||
export declare function makeBinaryFormat(): BinaryFormat;
|
||||
export declare function writeMapEntry(writer: IBinaryWriter, options: BinaryWriteOptions, field: FieldInfo & {
|
||||
kind: "map";
|
||||
}, key: string, value: any): void;
|
||||
+431
@@ -0,0 +1,431 @@
|
||||
"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.writeMapEntry = exports.makeBinaryFormat = void 0;
|
||||
const binary_encoding_js_1 = require("../binary-encoding.js");
|
||||
const field_wrapper_js_1 = require("./field-wrapper.js");
|
||||
const scalars_js_1 = require("./scalars.js");
|
||||
const assert_js_1 = require("./assert.js");
|
||||
const reflect_js_1 = require("./reflect.js");
|
||||
const scalar_js_1 = require("../scalar.js");
|
||||
const is_message_js_1 = require("../is-message.js");
|
||||
/* eslint-disable prefer-const,no-case-declarations,@typescript-eslint/no-explicit-any,@typescript-eslint/no-unsafe-argument,@typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-return */
|
||||
const unknownFieldsSymbol = Symbol("@bufbuild/protobuf/unknown-fields");
|
||||
// Default options for parsing binary data.
|
||||
const readDefaults = {
|
||||
readUnknownFields: true,
|
||||
readerFactory: (bytes) => new binary_encoding_js_1.BinaryReader(bytes),
|
||||
};
|
||||
// Default options for serializing binary data.
|
||||
const writeDefaults = {
|
||||
writeUnknownFields: true,
|
||||
writerFactory: () => new binary_encoding_js_1.BinaryWriter(),
|
||||
};
|
||||
function makeReadOptions(options) {
|
||||
return options ? Object.assign(Object.assign({}, readDefaults), options) : readDefaults;
|
||||
}
|
||||
function makeWriteOptions(options) {
|
||||
return options ? Object.assign(Object.assign({}, writeDefaults), options) : writeDefaults;
|
||||
}
|
||||
function makeBinaryFormat() {
|
||||
return {
|
||||
makeReadOptions,
|
||||
makeWriteOptions,
|
||||
listUnknownFields(message) {
|
||||
var _a;
|
||||
return (_a = message[unknownFieldsSymbol]) !== null && _a !== void 0 ? _a : [];
|
||||
},
|
||||
discardUnknownFields(message) {
|
||||
delete message[unknownFieldsSymbol];
|
||||
},
|
||||
writeUnknownFields(message, writer) {
|
||||
const m = message;
|
||||
const c = m[unknownFieldsSymbol];
|
||||
if (c) {
|
||||
for (const f of c) {
|
||||
writer.tag(f.no, f.wireType).raw(f.data);
|
||||
}
|
||||
}
|
||||
},
|
||||
onUnknownField(message, no, wireType, data) {
|
||||
const m = message;
|
||||
if (!Array.isArray(m[unknownFieldsSymbol])) {
|
||||
m[unknownFieldsSymbol] = [];
|
||||
}
|
||||
m[unknownFieldsSymbol].push({ no, wireType, data });
|
||||
},
|
||||
readMessage(message, reader, lengthOrEndTagFieldNo, options, delimitedMessageEncoding) {
|
||||
const type = message.getType();
|
||||
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
||||
const end = delimitedMessageEncoding
|
||||
? reader.len
|
||||
: reader.pos + lengthOrEndTagFieldNo;
|
||||
let fieldNo, wireType;
|
||||
while (reader.pos < end) {
|
||||
[fieldNo, wireType] = reader.tag();
|
||||
if (delimitedMessageEncoding === true &&
|
||||
wireType == binary_encoding_js_1.WireType.EndGroup) {
|
||||
break;
|
||||
}
|
||||
const field = type.fields.find(fieldNo);
|
||||
if (!field) {
|
||||
const data = reader.skip(wireType, fieldNo);
|
||||
if (options.readUnknownFields) {
|
||||
this.onUnknownField(message, fieldNo, wireType, data);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
readField(message, reader, field, wireType, options);
|
||||
}
|
||||
if (delimitedMessageEncoding && // eslint-disable-line @typescript-eslint/strict-boolean-expressions
|
||||
(wireType != binary_encoding_js_1.WireType.EndGroup || fieldNo !== lengthOrEndTagFieldNo)) {
|
||||
throw new Error(`invalid end group tag`);
|
||||
}
|
||||
},
|
||||
readField,
|
||||
writeMessage(message, writer, options) {
|
||||
const type = message.getType();
|
||||
for (const field of type.fields.byNumber()) {
|
||||
if (!(0, reflect_js_1.isFieldSet)(field, message)) {
|
||||
if (field.req) {
|
||||
throw new Error(`cannot encode field ${type.typeName}.${field.name} to binary: required field not set`);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
const value = field.oneof
|
||||
? message[field.oneof.localName].value
|
||||
: message[field.localName];
|
||||
writeField(field, value, writer, options);
|
||||
}
|
||||
if (options.writeUnknownFields) {
|
||||
this.writeUnknownFields(message, writer);
|
||||
}
|
||||
return writer;
|
||||
},
|
||||
writeField(field, value, writer, options) {
|
||||
// The behavior of our internal function has changed, it does no longer
|
||||
// accept `undefined` values for singular scalar and map.
|
||||
// For backwards-compatibility, we support the old form that is part of
|
||||
// the public API through the interface BinaryFormat.
|
||||
if (value === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
writeField(field, value, writer, options);
|
||||
},
|
||||
};
|
||||
}
|
||||
exports.makeBinaryFormat = makeBinaryFormat;
|
||||
function readField(target, // eslint-disable-line @typescript-eslint/no-explicit-any -- `any` is the best choice for dynamic access
|
||||
reader, field, wireType, options) {
|
||||
let { repeated, localName } = field;
|
||||
if (field.oneof) {
|
||||
target = target[field.oneof.localName];
|
||||
if (target.case != localName) {
|
||||
delete target.value;
|
||||
}
|
||||
target.case = localName;
|
||||
localName = "value";
|
||||
}
|
||||
switch (field.kind) {
|
||||
case "scalar":
|
||||
case "enum":
|
||||
const scalarType = field.kind == "enum" ? scalar_js_1.ScalarType.INT32 : field.T;
|
||||
let read = readScalar;
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-enum-comparison -- acceptable since it's covered by tests
|
||||
if (field.kind == "scalar" && field.L > 0) {
|
||||
read = readScalarLTString;
|
||||
}
|
||||
if (repeated) {
|
||||
let arr = target[localName]; // safe to assume presence of array, oneof cannot contain repeated values
|
||||
const isPacked = wireType == binary_encoding_js_1.WireType.LengthDelimited &&
|
||||
scalarType != scalar_js_1.ScalarType.STRING &&
|
||||
scalarType != scalar_js_1.ScalarType.BYTES;
|
||||
if (isPacked) {
|
||||
let e = reader.uint32() + reader.pos;
|
||||
while (reader.pos < e) {
|
||||
arr.push(read(reader, scalarType));
|
||||
}
|
||||
}
|
||||
else {
|
||||
arr.push(read(reader, scalarType));
|
||||
}
|
||||
}
|
||||
else {
|
||||
target[localName] = read(reader, scalarType);
|
||||
}
|
||||
break;
|
||||
case "message":
|
||||
const messageType = field.T;
|
||||
if (repeated) {
|
||||
// safe to assume presence of array, oneof cannot contain repeated values
|
||||
target[localName].push(readMessageField(reader, new messageType(), options, field));
|
||||
}
|
||||
else {
|
||||
if ((0, is_message_js_1.isMessage)(target[localName])) {
|
||||
readMessageField(reader, target[localName], options, field);
|
||||
}
|
||||
else {
|
||||
target[localName] = readMessageField(reader, new messageType(), options, field);
|
||||
if (messageType.fieldWrapper && !field.oneof && !field.repeated) {
|
||||
target[localName] = messageType.fieldWrapper.unwrapField(target[localName]);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "map":
|
||||
let [mapKey, mapVal] = readMapEntry(field, reader, options);
|
||||
// safe to assume presence of map object, oneof cannot contain repeated values
|
||||
target[localName][mapKey] = mapVal;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Read a message, avoiding MessageType.fromBinary() to re-use the
|
||||
// BinaryReadOptions and the IBinaryReader.
|
||||
function readMessageField(reader, message, options, field) {
|
||||
const format = message.getType().runtime.bin;
|
||||
const delimited = field === null || field === void 0 ? void 0 : field.delimited;
|
||||
format.readMessage(message, reader, delimited ? field.no : reader.uint32(), // eslint-disable-line @typescript-eslint/strict-boolean-expressions
|
||||
options, delimited);
|
||||
return message;
|
||||
}
|
||||
// Read a map field, expecting key field = 1, value field = 2
|
||||
function readMapEntry(field, reader, options) {
|
||||
const length = reader.uint32(), end = reader.pos + length;
|
||||
let key, val;
|
||||
while (reader.pos < end) {
|
||||
const [fieldNo] = reader.tag();
|
||||
switch (fieldNo) {
|
||||
case 1:
|
||||
key = readScalar(reader, field.K);
|
||||
break;
|
||||
case 2:
|
||||
switch (field.V.kind) {
|
||||
case "scalar":
|
||||
val = readScalar(reader, field.V.T);
|
||||
break;
|
||||
case "enum":
|
||||
val = reader.int32();
|
||||
break;
|
||||
case "message":
|
||||
val = readMessageField(reader, new field.V.T(), options, undefined);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (key === undefined) {
|
||||
key = (0, scalars_js_1.scalarZeroValue)(field.K, scalar_js_1.LongType.BIGINT);
|
||||
}
|
||||
if (typeof key != "string" && typeof key != "number") {
|
||||
key = key.toString();
|
||||
}
|
||||
if (val === undefined) {
|
||||
switch (field.V.kind) {
|
||||
case "scalar":
|
||||
val = (0, scalars_js_1.scalarZeroValue)(field.V.T, scalar_js_1.LongType.BIGINT);
|
||||
break;
|
||||
case "enum":
|
||||
val = field.V.T.values[0].no;
|
||||
break;
|
||||
case "message":
|
||||
val = new field.V.T();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return [key, val];
|
||||
}
|
||||
// Read a scalar value, but return 64 bit integral types (int64, uint64,
|
||||
// sint64, fixed64, sfixed64) as string instead of bigint.
|
||||
function readScalarLTString(reader, type) {
|
||||
const v = readScalar(reader, type);
|
||||
return typeof v == "bigint" ? v.toString() : v;
|
||||
}
|
||||
// Does not use scalarTypeInfo() for better performance.
|
||||
function readScalar(reader, type) {
|
||||
switch (type) {
|
||||
case scalar_js_1.ScalarType.STRING:
|
||||
return reader.string();
|
||||
case scalar_js_1.ScalarType.BOOL:
|
||||
return reader.bool();
|
||||
case scalar_js_1.ScalarType.DOUBLE:
|
||||
return reader.double();
|
||||
case scalar_js_1.ScalarType.FLOAT:
|
||||
return reader.float();
|
||||
case scalar_js_1.ScalarType.INT32:
|
||||
return reader.int32();
|
||||
case scalar_js_1.ScalarType.INT64:
|
||||
return reader.int64();
|
||||
case scalar_js_1.ScalarType.UINT64:
|
||||
return reader.uint64();
|
||||
case scalar_js_1.ScalarType.FIXED64:
|
||||
return reader.fixed64();
|
||||
case scalar_js_1.ScalarType.BYTES:
|
||||
return reader.bytes();
|
||||
case scalar_js_1.ScalarType.FIXED32:
|
||||
return reader.fixed32();
|
||||
case scalar_js_1.ScalarType.SFIXED32:
|
||||
return reader.sfixed32();
|
||||
case scalar_js_1.ScalarType.SFIXED64:
|
||||
return reader.sfixed64();
|
||||
case scalar_js_1.ScalarType.SINT64:
|
||||
return reader.sint64();
|
||||
case scalar_js_1.ScalarType.UINT32:
|
||||
return reader.uint32();
|
||||
case scalar_js_1.ScalarType.SINT32:
|
||||
return reader.sint32();
|
||||
}
|
||||
}
|
||||
function writeField(field, value, writer, options) {
|
||||
(0, assert_js_1.assert)(value !== undefined);
|
||||
const repeated = field.repeated;
|
||||
switch (field.kind) {
|
||||
case "scalar":
|
||||
case "enum":
|
||||
let scalarType = field.kind == "enum" ? scalar_js_1.ScalarType.INT32 : field.T;
|
||||
if (repeated) {
|
||||
(0, assert_js_1.assert)(Array.isArray(value));
|
||||
if (field.packed) {
|
||||
writePacked(writer, scalarType, field.no, value);
|
||||
}
|
||||
else {
|
||||
for (const item of value) {
|
||||
writeScalar(writer, scalarType, field.no, item);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
writeScalar(writer, scalarType, field.no, value);
|
||||
}
|
||||
break;
|
||||
case "message":
|
||||
if (repeated) {
|
||||
(0, assert_js_1.assert)(Array.isArray(value));
|
||||
for (const item of value) {
|
||||
writeMessageField(writer, options, field, item);
|
||||
}
|
||||
}
|
||||
else {
|
||||
writeMessageField(writer, options, field, value);
|
||||
}
|
||||
break;
|
||||
case "map":
|
||||
(0, assert_js_1.assert)(typeof value == "object" && value != null);
|
||||
for (const [key, val] of Object.entries(value)) {
|
||||
writeMapEntry(writer, options, field, key, val);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
function writeMapEntry(writer, options, field, key, value) {
|
||||
writer.tag(field.no, binary_encoding_js_1.WireType.LengthDelimited);
|
||||
writer.fork();
|
||||
// javascript only allows number or string for object properties
|
||||
// we convert from our representation to the protobuf type
|
||||
let keyValue = key;
|
||||
// eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check -- we deliberately handle just the special cases for map keys
|
||||
switch (field.K) {
|
||||
case scalar_js_1.ScalarType.INT32:
|
||||
case scalar_js_1.ScalarType.FIXED32:
|
||||
case scalar_js_1.ScalarType.UINT32:
|
||||
case scalar_js_1.ScalarType.SFIXED32:
|
||||
case scalar_js_1.ScalarType.SINT32:
|
||||
keyValue = Number.parseInt(key);
|
||||
break;
|
||||
case scalar_js_1.ScalarType.BOOL:
|
||||
(0, assert_js_1.assert)(key == "true" || key == "false");
|
||||
keyValue = key == "true";
|
||||
break;
|
||||
}
|
||||
// write key, expecting key field number = 1
|
||||
writeScalar(writer, field.K, 1, keyValue);
|
||||
// write value, expecting value field number = 2
|
||||
switch (field.V.kind) {
|
||||
case "scalar":
|
||||
writeScalar(writer, field.V.T, 2, value);
|
||||
break;
|
||||
case "enum":
|
||||
writeScalar(writer, scalar_js_1.ScalarType.INT32, 2, value);
|
||||
break;
|
||||
case "message":
|
||||
(0, assert_js_1.assert)(value !== undefined);
|
||||
writer.tag(2, binary_encoding_js_1.WireType.LengthDelimited).bytes(value.toBinary(options));
|
||||
break;
|
||||
}
|
||||
writer.join();
|
||||
}
|
||||
exports.writeMapEntry = writeMapEntry;
|
||||
// Value must not be undefined
|
||||
function writeMessageField(writer, options, field, value) {
|
||||
const message = (0, field_wrapper_js_1.wrapField)(field.T, value);
|
||||
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
||||
if (field.delimited)
|
||||
writer
|
||||
.tag(field.no, binary_encoding_js_1.WireType.StartGroup)
|
||||
.raw(message.toBinary(options))
|
||||
.tag(field.no, binary_encoding_js_1.WireType.EndGroup);
|
||||
else
|
||||
writer
|
||||
.tag(field.no, binary_encoding_js_1.WireType.LengthDelimited)
|
||||
.bytes(message.toBinary(options));
|
||||
}
|
||||
function writeScalar(writer, type, fieldNo, value) {
|
||||
(0, assert_js_1.assert)(value !== undefined);
|
||||
let [wireType, method] = scalarTypeInfo(type);
|
||||
writer.tag(fieldNo, wireType)[method](value);
|
||||
}
|
||||
function writePacked(writer, type, fieldNo, value) {
|
||||
if (!value.length) {
|
||||
return;
|
||||
}
|
||||
writer.tag(fieldNo, binary_encoding_js_1.WireType.LengthDelimited).fork();
|
||||
let [, method] = scalarTypeInfo(type);
|
||||
for (let i = 0; i < value.length; i++) {
|
||||
writer[method](value[i]);
|
||||
}
|
||||
writer.join();
|
||||
}
|
||||
/**
|
||||
* Get information for writing a scalar value.
|
||||
*
|
||||
* Returns tuple:
|
||||
* [0]: appropriate WireType
|
||||
* [1]: name of the appropriate method of IBinaryWriter
|
||||
* [2]: whether the given value is a default value for proto3 semantics
|
||||
*
|
||||
* If argument `value` is omitted, [2] is always false.
|
||||
*/
|
||||
// TODO replace call-sites writeScalar() and writePacked(), then remove
|
||||
function scalarTypeInfo(type) {
|
||||
let wireType = binary_encoding_js_1.WireType.Varint;
|
||||
// eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check -- INT32, UINT32, SINT32 are covered by the defaults
|
||||
switch (type) {
|
||||
case scalar_js_1.ScalarType.BYTES:
|
||||
case scalar_js_1.ScalarType.STRING:
|
||||
wireType = binary_encoding_js_1.WireType.LengthDelimited;
|
||||
break;
|
||||
case scalar_js_1.ScalarType.DOUBLE:
|
||||
case scalar_js_1.ScalarType.FIXED64:
|
||||
case scalar_js_1.ScalarType.SFIXED64:
|
||||
wireType = binary_encoding_js_1.WireType.Bit64;
|
||||
break;
|
||||
case scalar_js_1.ScalarType.FIXED32:
|
||||
case scalar_js_1.ScalarType.SFIXED32:
|
||||
case scalar_js_1.ScalarType.FLOAT:
|
||||
wireType = binary_encoding_js_1.WireType.Bit32;
|
||||
break;
|
||||
}
|
||||
const method = scalar_js_1.ScalarType[type].toLowerCase();
|
||||
return [wireType, method];
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
import type { EnumType, EnumValueInfo } from "../enum.js";
|
||||
/**
|
||||
* Represents a generated enum.
|
||||
*/
|
||||
export interface EnumObject {
|
||||
[key: number]: string;
|
||||
[k: string]: number | string;
|
||||
}
|
||||
/**
|
||||
* Get reflection information from a generated enum.
|
||||
* If this function is called on something other than a generated
|
||||
* enum, it raises an error.
|
||||
*/
|
||||
export declare function getEnumType(enumObject: EnumObject): EnumType;
|
||||
/**
|
||||
* Sets reflection information on a generated enum.
|
||||
*/
|
||||
export declare function setEnumType(enumObject: EnumObject, typeName: string, values: Omit<EnumValueInfo, "localName">[], opt?: {}): void;
|
||||
/**
|
||||
* Create a new EnumType with the given values.
|
||||
*/
|
||||
export declare function makeEnumType(typeName: string, values: (EnumValueInfo | Omit<EnumValueInfo, "localName">)[], _opt?: {}): EnumType;
|
||||
/**
|
||||
* Create a new enum object with the given values.
|
||||
* Sets reflection information.
|
||||
*/
|
||||
export declare function makeEnum(typeName: string, values: (EnumValueInfo | Omit<EnumValueInfo, "localName">)[], opt?: {}): EnumObject;
|
||||
+94
@@ -0,0 +1,94 @@
|
||||
"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.makeEnum = exports.makeEnumType = exports.setEnumType = exports.getEnumType = void 0;
|
||||
const assert_js_1 = require("./assert.js");
|
||||
const enumTypeSymbol = Symbol("@bufbuild/protobuf/enum-type");
|
||||
/**
|
||||
* Get reflection information from a generated enum.
|
||||
* If this function is called on something other than a generated
|
||||
* enum, it raises an error.
|
||||
*/
|
||||
function getEnumType(enumObject) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-explicit-any
|
||||
const t = enumObject[enumTypeSymbol];
|
||||
(0, assert_js_1.assert)(t, "missing enum type on enum object");
|
||||
return t; // eslint-disable-line @typescript-eslint/no-unsafe-return
|
||||
}
|
||||
exports.getEnumType = getEnumType;
|
||||
/**
|
||||
* Sets reflection information on a generated enum.
|
||||
*/
|
||||
function setEnumType(enumObject, typeName, values, opt) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any
|
||||
enumObject[enumTypeSymbol] = makeEnumType(typeName, values.map((v) => ({
|
||||
no: v.no,
|
||||
name: v.name,
|
||||
localName: enumObject[v.no],
|
||||
})), opt);
|
||||
}
|
||||
exports.setEnumType = setEnumType;
|
||||
/**
|
||||
* Create a new EnumType with the given values.
|
||||
*/
|
||||
function makeEnumType(typeName, values,
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
_opt) {
|
||||
const names = Object.create(null);
|
||||
const numbers = Object.create(null);
|
||||
const normalValues = [];
|
||||
for (const value of values) {
|
||||
// We do not surface options at this time
|
||||
// const value: EnumValueInfo = {...v, options: v.options ?? emptyReadonlyObject};
|
||||
const n = normalizeEnumValue(value);
|
||||
normalValues.push(n);
|
||||
names[value.name] = n;
|
||||
numbers[value.no] = n;
|
||||
}
|
||||
return {
|
||||
typeName,
|
||||
values: normalValues,
|
||||
// We do not surface options at this time
|
||||
// options: opt?.options ?? Object.create(null),
|
||||
findName(name) {
|
||||
return names[name];
|
||||
},
|
||||
findNumber(no) {
|
||||
return numbers[no];
|
||||
},
|
||||
};
|
||||
}
|
||||
exports.makeEnumType = makeEnumType;
|
||||
/**
|
||||
* Create a new enum object with the given values.
|
||||
* Sets reflection information.
|
||||
*/
|
||||
function makeEnum(typeName, values, opt) {
|
||||
const enumObject = {};
|
||||
for (const value of values) {
|
||||
const n = normalizeEnumValue(value);
|
||||
enumObject[n.localName] = n.no;
|
||||
enumObject[n.no] = n.localName;
|
||||
}
|
||||
setEnumType(enumObject, typeName, values, opt);
|
||||
return enumObject;
|
||||
}
|
||||
exports.makeEnum = makeEnum;
|
||||
function normalizeEnumValue(value) {
|
||||
if ("localName" in value) {
|
||||
return value;
|
||||
}
|
||||
return Object.assign(Object.assign({}, value), { localName: value.name });
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
import type { Extension } from "../extension.js";
|
||||
import type { AnyMessage, Message } from "../message.js";
|
||||
import type { FieldInfo, OneofInfo, PartialFieldInfo } from "../field.js";
|
||||
import { WireType } from "../binary-encoding.js";
|
||||
import type { ProtoRuntime } from "./proto-runtime.js";
|
||||
import type { MessageType } from "../message-type.js";
|
||||
export type ExtensionFieldSource = extensionFieldRules<FieldInfo> | extensionFieldRules<PartialFieldInfo> | (() => extensionFieldRules<FieldInfo>) | (() => extensionFieldRules<PartialFieldInfo>);
|
||||
type extensionFieldRules<T extends FieldInfo | PartialFieldInfo> = T extends {
|
||||
kind: "map";
|
||||
} ? never : T extends {
|
||||
oneof: string;
|
||||
} ? never : T extends {
|
||||
oneof: OneofInfo;
|
||||
} ? never : Omit<T, "name"> & Partial<Pick<T, "name">>;
|
||||
/**
|
||||
* Create a new extension using the given runtime.
|
||||
*/
|
||||
export declare function makeExtension<E extends Message<E> = AnyMessage, V = unknown>(runtime: ProtoRuntime, typeName: string, extendee: MessageType<E>, field: ExtensionFieldSource): Extension<E, V>;
|
||||
/**
|
||||
* Create a container that allows us to read extension fields into it with the
|
||||
* same logic as regular fields.
|
||||
*/
|
||||
export declare function createExtensionContainer<E extends Message<E> = AnyMessage, V = unknown>(extension: Extension<E, V>): [Record<string, V>, () => V];
|
||||
type UnknownField = {
|
||||
no: number;
|
||||
wireType: WireType;
|
||||
data: Uint8Array;
|
||||
};
|
||||
type UnknownFields = ReadonlyArray<UnknownField>;
|
||||
/**
|
||||
* Helper to filter unknown fields, optimized based on field type.
|
||||
*/
|
||||
export declare function filterUnknownFields(unknownFields: UnknownFields, field: Pick<FieldInfo, "no" | "kind" | "repeated">): UnknownField[];
|
||||
export {};
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
"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.filterUnknownFields = exports.createExtensionContainer = exports.makeExtension = void 0;
|
||||
const scalars_js_1 = require("./scalars.js");
|
||||
/**
|
||||
* Create a new extension using the given runtime.
|
||||
*/
|
||||
function makeExtension(runtime, typeName, extendee, field) {
|
||||
let fi;
|
||||
return {
|
||||
typeName,
|
||||
extendee,
|
||||
get field() {
|
||||
if (!fi) {
|
||||
const i = (typeof field == "function" ? field() : field);
|
||||
i.name = typeName.split(".").pop();
|
||||
i.jsonName = `[${typeName}]`;
|
||||
fi = runtime.util.newFieldList([i]).list()[0];
|
||||
}
|
||||
return fi;
|
||||
},
|
||||
runtime,
|
||||
};
|
||||
}
|
||||
exports.makeExtension = makeExtension;
|
||||
/**
|
||||
* Create a container that allows us to read extension fields into it with the
|
||||
* same logic as regular fields.
|
||||
*/
|
||||
function createExtensionContainer(extension) {
|
||||
const localName = extension.field.localName;
|
||||
const container = Object.create(null);
|
||||
container[localName] = initExtensionField(extension);
|
||||
return [container, () => container[localName]];
|
||||
}
|
||||
exports.createExtensionContainer = createExtensionContainer;
|
||||
function initExtensionField(ext) {
|
||||
const field = ext.field;
|
||||
if (field.repeated) {
|
||||
return [];
|
||||
}
|
||||
if (field.default !== undefined) {
|
||||
return field.default;
|
||||
}
|
||||
switch (field.kind) {
|
||||
case "enum":
|
||||
return field.T.values[0].no;
|
||||
case "scalar":
|
||||
return (0, scalars_js_1.scalarZeroValue)(field.T, field.L);
|
||||
case "message":
|
||||
// eslint-disable-next-line no-case-declarations
|
||||
const T = field.T, value = new T();
|
||||
return T.fieldWrapper ? T.fieldWrapper.unwrapField(value) : value;
|
||||
case "map":
|
||||
throw "map fields are not allowed to be extensions";
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Helper to filter unknown fields, optimized based on field type.
|
||||
*/
|
||||
function filterUnknownFields(unknownFields, field) {
|
||||
if (!field.repeated && (field.kind == "enum" || field.kind == "scalar")) {
|
||||
// singular scalar fields do not merge, we pick the last
|
||||
for (let i = unknownFields.length - 1; i >= 0; --i) {
|
||||
if (unknownFields[i].no == field.no) {
|
||||
return [unknownFields[i]];
|
||||
}
|
||||
}
|
||||
return [];
|
||||
}
|
||||
return unknownFields.filter((uf) => uf.no === field.no);
|
||||
}
|
||||
exports.filterUnknownFields = filterUnknownFields;
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
import { Edition, FeatureSet, FeatureSetDefaults } from "../google/protobuf/descriptor_pb.js";
|
||||
import type { BinaryReadOptions, BinaryWriteOptions } from "../binary-format.js";
|
||||
/**
|
||||
* A merged google.protobuf.FeaturesSet, with all fields guaranteed to be set.
|
||||
*/
|
||||
export type MergedFeatureSet = FeatureSet & Required<FeatureSet>;
|
||||
/**
|
||||
* A function that resolves features.
|
||||
*
|
||||
* If no feature set is provided, the default feature set for the edition is
|
||||
* returned. If features are provided, they are merged into the edition default
|
||||
* features.
|
||||
*/
|
||||
export type FeatureResolverFn = (a?: FeatureSet, b?: FeatureSet) => MergedFeatureSet;
|
||||
/**
|
||||
* Create an edition feature resolver with the given feature set defaults, or
|
||||
* the feature set defaults supported by @bufbuild/protobuf.
|
||||
*/
|
||||
export declare function createFeatureResolver(edition: Edition, compiledFeatureSetDefaults?: FeatureSetDefaults, serializationOptions?: Partial<BinaryReadOptions & BinaryWriteOptions>): FeatureResolverFn;
|
||||
+120
@@ -0,0 +1,120 @@
|
||||
"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.createFeatureResolver = void 0;
|
||||
const descriptor_pb_js_1 = require("../google/protobuf/descriptor_pb.js");
|
||||
const proto_base64_js_1 = require("../proto-base64.js");
|
||||
/**
|
||||
* Return the edition feature defaults supported by @bufbuild/protobuf.
|
||||
*/
|
||||
function getFeatureSetDefaults(options) {
|
||||
return descriptor_pb_js_1.FeatureSetDefaults.fromBinary(proto_base64_js_1.protoBase64.dec(
|
||||
/*upstream-inject-feature-defaults-start*/ "ChMY5gciACoMCAEQAhgCIAMoATACChMY5wciACoMCAIQARgBIAIoATABChMY6AciDAgBEAEYASACKAEwASoAIOYHKOgH" /*upstream-inject-feature-defaults-end*/), options);
|
||||
}
|
||||
/**
|
||||
* Create an edition feature resolver with the given feature set defaults, or
|
||||
* the feature set defaults supported by @bufbuild/protobuf.
|
||||
*/
|
||||
function createFeatureResolver(edition, compiledFeatureSetDefaults, serializationOptions) {
|
||||
var _a;
|
||||
const fds = compiledFeatureSetDefaults !== null && compiledFeatureSetDefaults !== void 0 ? compiledFeatureSetDefaults : getFeatureSetDefaults(serializationOptions);
|
||||
const min = fds.minimumEdition;
|
||||
const max = fds.maximumEdition;
|
||||
if (min === undefined ||
|
||||
max === undefined ||
|
||||
fds.defaults.some((d) => d.edition === undefined)) {
|
||||
throw new Error("Invalid FeatureSetDefaults");
|
||||
}
|
||||
if (edition < min) {
|
||||
throw new Error(`Edition ${descriptor_pb_js_1.Edition[edition]} is earlier than the minimum supported edition ${descriptor_pb_js_1.Edition[min]}`);
|
||||
}
|
||||
if (max < edition) {
|
||||
throw new Error(`Edition ${descriptor_pb_js_1.Edition[edition]} is later than the maximum supported edition ${descriptor_pb_js_1.Edition[max]}`);
|
||||
}
|
||||
let highestMatch = undefined;
|
||||
for (const c of fds.defaults) {
|
||||
const e = (_a = c.edition) !== null && _a !== void 0 ? _a : 0;
|
||||
if (e > edition) {
|
||||
continue;
|
||||
}
|
||||
if (highestMatch !== undefined && highestMatch.e > e) {
|
||||
continue;
|
||||
}
|
||||
let f;
|
||||
if (c.fixedFeatures && c.overridableFeatures) {
|
||||
f = c.fixedFeatures;
|
||||
f.fromBinary(c.overridableFeatures.toBinary());
|
||||
}
|
||||
else if (c.fixedFeatures) {
|
||||
f = c.fixedFeatures;
|
||||
}
|
||||
else if (c.overridableFeatures) {
|
||||
f = c.overridableFeatures;
|
||||
}
|
||||
else {
|
||||
f = new descriptor_pb_js_1.FeatureSet();
|
||||
}
|
||||
highestMatch = {
|
||||
e,
|
||||
f,
|
||||
};
|
||||
}
|
||||
if (highestMatch === undefined) {
|
||||
throw new Error(`No valid default found for edition ${descriptor_pb_js_1.Edition[edition]}`);
|
||||
}
|
||||
const featureSetBin = highestMatch.f.toBinary(serializationOptions);
|
||||
return (...rest) => {
|
||||
const f = descriptor_pb_js_1.FeatureSet.fromBinary(featureSetBin, serializationOptions);
|
||||
for (const c of rest) {
|
||||
if (c !== undefined) {
|
||||
f.fromBinary(c.toBinary(serializationOptions), serializationOptions);
|
||||
}
|
||||
}
|
||||
if (!validateMergedFeatures(f)) {
|
||||
throw new Error(`Invalid FeatureSet for edition ${descriptor_pb_js_1.Edition[edition]}`);
|
||||
}
|
||||
return f;
|
||||
};
|
||||
}
|
||||
exports.createFeatureResolver = createFeatureResolver;
|
||||
// When protoc generates google.protobuf.FeatureSetDefaults, it ensures that
|
||||
// fields are not repeated or required, do not use oneof, and have a default
|
||||
// value.
|
||||
//
|
||||
// When features for an element are resolved, features of the element and its
|
||||
// parents are merged into the default FeatureSet for the edition. Because unset
|
||||
// fields in the FeatureSet of an element do not unset the default FeatureSet
|
||||
// values, a resolved FeatureSet is guaranteed to have all fields set. This is
|
||||
// also the case for extensions to FeatureSet that a user might provide, and for
|
||||
// features from the future.
|
||||
//
|
||||
// We cannot exhaustively validate correctness of FeatureSetDefaults at runtime
|
||||
// without knowing the schema: If no value for a feature is provided, we do not
|
||||
// know that it exists at all.
|
||||
//
|
||||
// As a sanity check, we validate that all fields known to our version of
|
||||
// FeatureSet are set.
|
||||
function validateMergedFeatures(featureSet) {
|
||||
for (const fi of descriptor_pb_js_1.FeatureSet.fields.list()) {
|
||||
const v = featureSet[fi.localName];
|
||||
if (v === undefined) {
|
||||
return false;
|
||||
}
|
||||
if (fi.kind == "enum" && v === 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
import type { FieldInfo, OneofInfo, PartialFieldInfo } from "../field.js";
|
||||
import type { FieldList } from "../field-list.js";
|
||||
export type FieldListSource = readonly PartialFieldInfo[] | readonly FieldInfo[] | (() => readonly PartialFieldInfo[]) | (() => readonly FieldInfo[]);
|
||||
export declare class InternalFieldList implements FieldList {
|
||||
private readonly _fields;
|
||||
private readonly _normalizer;
|
||||
private all?;
|
||||
private numbersAsc?;
|
||||
private jsonNames?;
|
||||
private numbers?;
|
||||
private members?;
|
||||
constructor(fields: FieldListSource, normalizer: (p: FieldListSource) => FieldInfo[]);
|
||||
findJsonName(jsonName: string): FieldInfo | undefined;
|
||||
find(fieldNo: number): FieldInfo | undefined;
|
||||
list(): readonly FieldInfo[];
|
||||
byNumber(): readonly FieldInfo[];
|
||||
byMember(): readonly (FieldInfo | OneofInfo)[];
|
||||
}
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
"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.InternalFieldList = void 0;
|
||||
class InternalFieldList {
|
||||
constructor(fields, normalizer) {
|
||||
this._fields = fields;
|
||||
this._normalizer = normalizer;
|
||||
}
|
||||
findJsonName(jsonName) {
|
||||
if (!this.jsonNames) {
|
||||
const t = {};
|
||||
for (const f of this.list()) {
|
||||
t[f.jsonName] = t[f.name] = f;
|
||||
}
|
||||
this.jsonNames = t;
|
||||
}
|
||||
return this.jsonNames[jsonName];
|
||||
}
|
||||
find(fieldNo) {
|
||||
if (!this.numbers) {
|
||||
const t = {};
|
||||
for (const f of this.list()) {
|
||||
t[f.no] = f;
|
||||
}
|
||||
this.numbers = t;
|
||||
}
|
||||
return this.numbers[fieldNo];
|
||||
}
|
||||
list() {
|
||||
if (!this.all) {
|
||||
this.all = this._normalizer(this._fields);
|
||||
}
|
||||
return this.all;
|
||||
}
|
||||
byNumber() {
|
||||
if (!this.numbersAsc) {
|
||||
this.numbersAsc = this.list()
|
||||
.concat()
|
||||
.sort((a, b) => a.no - b.no);
|
||||
}
|
||||
return this.numbersAsc;
|
||||
}
|
||||
byMember() {
|
||||
if (!this.members) {
|
||||
this.members = [];
|
||||
const a = this.members;
|
||||
let o;
|
||||
for (const f of this.list()) {
|
||||
if (f.oneof) {
|
||||
if (f.oneof !== o) {
|
||||
o = f.oneof;
|
||||
a.push(o);
|
||||
}
|
||||
}
|
||||
else {
|
||||
a.push(f);
|
||||
}
|
||||
}
|
||||
}
|
||||
return this.members;
|
||||
}
|
||||
}
|
||||
exports.InternalFieldList = InternalFieldList;
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
import type { FieldListSource } from "./field-list.js";
|
||||
import type { FieldInfo } from "../field.js";
|
||||
/**
|
||||
* Convert a collection of field info to an array of normalized FieldInfo.
|
||||
*
|
||||
* The argument `packedByDefault` specifies whether fields that do not specify
|
||||
* `packed` should be packed (proto3) or unpacked (proto2).
|
||||
*/
|
||||
export declare function normalizeFieldInfos(fieldInfos: FieldListSource, packedByDefault: boolean): FieldInfo[];
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
"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.normalizeFieldInfos = void 0;
|
||||
const field_js_1 = require("./field.js");
|
||||
const names_js_1 = require("./names.js");
|
||||
const scalar_js_1 = require("../scalar.js");
|
||||
/**
|
||||
* Convert a collection of field info to an array of normalized FieldInfo.
|
||||
*
|
||||
* The argument `packedByDefault` specifies whether fields that do not specify
|
||||
* `packed` should be packed (proto3) or unpacked (proto2).
|
||||
*/
|
||||
function normalizeFieldInfos(fieldInfos, packedByDefault) {
|
||||
var _a, _b, _c, _d, _e, _f;
|
||||
const r = [];
|
||||
let o;
|
||||
for (const field of typeof fieldInfos == "function"
|
||||
? fieldInfos()
|
||||
: fieldInfos) {
|
||||
const f = field;
|
||||
f.localName = (0, names_js_1.localFieldName)(field.name, field.oneof !== undefined);
|
||||
f.jsonName = (_a = field.jsonName) !== null && _a !== void 0 ? _a : (0, names_js_1.fieldJsonName)(field.name);
|
||||
f.repeated = (_b = field.repeated) !== null && _b !== void 0 ? _b : false;
|
||||
if (field.kind == "scalar") {
|
||||
f.L = (_c = field.L) !== null && _c !== void 0 ? _c : scalar_js_1.LongType.BIGINT;
|
||||
}
|
||||
f.delimited = (_d = field.delimited) !== null && _d !== void 0 ? _d : false;
|
||||
f.req = (_e = field.req) !== null && _e !== void 0 ? _e : false;
|
||||
f.opt = (_f = field.opt) !== null && _f !== void 0 ? _f : false;
|
||||
if (field.packed === undefined) {
|
||||
if (packedByDefault) {
|
||||
f.packed =
|
||||
field.kind == "enum" ||
|
||||
(field.kind == "scalar" &&
|
||||
field.T != scalar_js_1.ScalarType.BYTES &&
|
||||
field.T != scalar_js_1.ScalarType.STRING);
|
||||
}
|
||||
else {
|
||||
f.packed = false;
|
||||
}
|
||||
}
|
||||
// We do not surface options at this time
|
||||
// f.options = field.options ?? emptyReadonlyObject;
|
||||
if (field.oneof !== undefined) {
|
||||
const ooname = typeof field.oneof == "string" ? field.oneof : field.oneof.name;
|
||||
if (!o || o.name != ooname) {
|
||||
o = new field_js_1.InternalOneofInfo(ooname);
|
||||
}
|
||||
f.oneof = o;
|
||||
o.addField(f);
|
||||
}
|
||||
r.push(f);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
exports.normalizeFieldInfos = normalizeFieldInfos;
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
import { Message } from "../message.js";
|
||||
import type { MessageType } from "../message-type.js";
|
||||
import type { DescExtension, DescField } from "../descriptor-set.js";
|
||||
import { ScalarType } from "../scalar.js";
|
||||
/**
|
||||
* A field wrapper unwraps a message to a primitive value that is more
|
||||
* ergonomic for use as a message field.
|
||||
*
|
||||
* Note that this feature exists for google/protobuf/wrappers.proto
|
||||
* and cannot be used to arbitrarily modify types in generated code.
|
||||
*/
|
||||
export interface FieldWrapper<T extends Message<T> = any, U = any> {
|
||||
wrapField(value: U): T;
|
||||
unwrapField(value: T): U;
|
||||
}
|
||||
/**
|
||||
* Wrap a primitive message field value in its corresponding wrapper
|
||||
* message. This function is idempotent.
|
||||
*/
|
||||
export declare function wrapField<T extends Message<T>>(type: MessageType<T>, value: any): T;
|
||||
/**
|
||||
* If the given field uses one of the well-known wrapper types, return
|
||||
* the primitive type it wraps.
|
||||
*/
|
||||
export declare function getUnwrappedFieldType(field: DescField | DescExtension): ScalarType | undefined;
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
"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.getUnwrappedFieldType = exports.wrapField = void 0;
|
||||
const scalar_js_1 = require("../scalar.js");
|
||||
const is_message_js_1 = require("../is-message.js");
|
||||
/**
|
||||
* Wrap a primitive message field value in its corresponding wrapper
|
||||
* message. This function is idempotent.
|
||||
*/
|
||||
function wrapField(type, value) {
|
||||
if ((0, is_message_js_1.isMessage)(value) || !type.fieldWrapper) {
|
||||
return value;
|
||||
}
|
||||
return type.fieldWrapper.wrapField(value);
|
||||
}
|
||||
exports.wrapField = wrapField;
|
||||
/**
|
||||
* If the given field uses one of the well-known wrapper types, return
|
||||
* the primitive type it wraps.
|
||||
*/
|
||||
function getUnwrappedFieldType(field) {
|
||||
if (field.fieldKind !== "message") {
|
||||
return undefined;
|
||||
}
|
||||
if (field.repeated) {
|
||||
return undefined;
|
||||
}
|
||||
if (field.oneof != undefined) {
|
||||
return undefined;
|
||||
}
|
||||
return wktWrapperToScalarType[field.message.typeName];
|
||||
}
|
||||
exports.getUnwrappedFieldType = getUnwrappedFieldType;
|
||||
const wktWrapperToScalarType = {
|
||||
"google.protobuf.DoubleValue": scalar_js_1.ScalarType.DOUBLE,
|
||||
"google.protobuf.FloatValue": scalar_js_1.ScalarType.FLOAT,
|
||||
"google.protobuf.Int64Value": scalar_js_1.ScalarType.INT64,
|
||||
"google.protobuf.UInt64Value": scalar_js_1.ScalarType.UINT64,
|
||||
"google.protobuf.Int32Value": scalar_js_1.ScalarType.INT32,
|
||||
"google.protobuf.UInt32Value": scalar_js_1.ScalarType.UINT32,
|
||||
"google.protobuf.BoolValue": scalar_js_1.ScalarType.BOOL,
|
||||
"google.protobuf.StringValue": scalar_js_1.ScalarType.STRING,
|
||||
"google.protobuf.BytesValue": scalar_js_1.ScalarType.BYTES,
|
||||
};
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
import type { FieldInfo, OneofInfo } from "../field.js";
|
||||
export declare class InternalOneofInfo implements OneofInfo {
|
||||
readonly kind = "oneof";
|
||||
readonly name: string;
|
||||
readonly localName: string;
|
||||
readonly repeated = false;
|
||||
readonly packed = false;
|
||||
readonly opt = false;
|
||||
readonly req = false;
|
||||
readonly default: undefined;
|
||||
readonly fields: FieldInfo[];
|
||||
private _lookup?;
|
||||
constructor(name: string);
|
||||
addField(field: FieldInfo): void;
|
||||
findField(localName: string): FieldInfo | undefined;
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
"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.InternalOneofInfo = void 0;
|
||||
const names_js_1 = require("./names.js");
|
||||
const assert_js_1 = require("./assert.js");
|
||||
class InternalOneofInfo {
|
||||
constructor(name) {
|
||||
this.kind = "oneof";
|
||||
this.repeated = false;
|
||||
this.packed = false;
|
||||
this.opt = false;
|
||||
this.req = false;
|
||||
this.default = undefined;
|
||||
this.fields = [];
|
||||
this.name = name;
|
||||
this.localName = (0, names_js_1.localOneofName)(name);
|
||||
}
|
||||
addField(field) {
|
||||
(0, assert_js_1.assert)(field.oneof === this, `field ${field.name} not one of ${this.name}`);
|
||||
this.fields.push(field);
|
||||
}
|
||||
findField(localName) {
|
||||
if (!this._lookup) {
|
||||
this._lookup = Object.create(null);
|
||||
for (let i = 0; i < this.fields.length; i++) {
|
||||
this._lookup[this.fields[i].localName] = this.fields[i];
|
||||
}
|
||||
}
|
||||
return this._lookup[localName];
|
||||
}
|
||||
}
|
||||
exports.InternalOneofInfo = InternalOneofInfo;
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
import type { JsonFormat } from "../json-format.js";
|
||||
export declare function makeJsonFormat(): JsonFormat;
|
||||
+626
@@ -0,0 +1,626 @@
|
||||
"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.makeJsonFormat = void 0;
|
||||
const assert_js_1 = require("./assert.js");
|
||||
const proto_int64_js_1 = require("../proto-int64.js");
|
||||
const proto_base64_js_1 = require("../proto-base64.js");
|
||||
const extensions_js_1 = require("./extensions.js");
|
||||
const extension_accessor_js_1 = require("../extension-accessor.js");
|
||||
const reflect_js_1 = require("./reflect.js");
|
||||
const field_wrapper_js_1 = require("./field-wrapper.js");
|
||||
const scalars_js_1 = require("./scalars.js");
|
||||
const scalars_js_2 = require("./scalars.js");
|
||||
const scalar_js_1 = require("../scalar.js");
|
||||
const is_message_js_1 = require("../is-message.js");
|
||||
/* eslint-disable no-case-declarations,@typescript-eslint/no-unsafe-argument,@typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-call */
|
||||
// Default options for parsing JSON.
|
||||
const jsonReadDefaults = {
|
||||
ignoreUnknownFields: false,
|
||||
};
|
||||
// Default options for serializing to JSON.
|
||||
const jsonWriteDefaults = {
|
||||
emitDefaultValues: false,
|
||||
enumAsInteger: false,
|
||||
useProtoFieldName: false,
|
||||
prettySpaces: 0,
|
||||
};
|
||||
function makeReadOptions(options) {
|
||||
return options ? Object.assign(Object.assign({}, jsonReadDefaults), options) : jsonReadDefaults;
|
||||
}
|
||||
function makeWriteOptions(options) {
|
||||
return options ? Object.assign(Object.assign({}, jsonWriteDefaults), options) : jsonWriteDefaults;
|
||||
}
|
||||
const tokenNull = Symbol();
|
||||
const tokenIgnoredUnknownEnum = Symbol();
|
||||
function makeJsonFormat() {
|
||||
return {
|
||||
makeReadOptions,
|
||||
makeWriteOptions,
|
||||
readMessage(type, json, options, message) {
|
||||
if (json == null || Array.isArray(json) || typeof json != "object") {
|
||||
throw new Error(`cannot decode message ${type.typeName} from JSON: ${debugJsonValue(json)}`);
|
||||
}
|
||||
message = message !== null && message !== void 0 ? message : new type();
|
||||
const oneofSeen = new Map();
|
||||
const registry = options.typeRegistry;
|
||||
for (const [jsonKey, jsonValue] of Object.entries(json)) {
|
||||
const field = type.fields.findJsonName(jsonKey);
|
||||
if (field) {
|
||||
if (field.oneof) {
|
||||
if (jsonValue === null && field.kind == "scalar") {
|
||||
// see conformance test Required.Proto3.JsonInput.OneofFieldNull{First,Second}
|
||||
continue;
|
||||
}
|
||||
const seen = oneofSeen.get(field.oneof);
|
||||
if (seen !== undefined) {
|
||||
throw new Error(`cannot decode message ${type.typeName} from JSON: multiple keys for oneof "${field.oneof.name}" present: "${seen}", "${jsonKey}"`);
|
||||
}
|
||||
oneofSeen.set(field.oneof, jsonKey);
|
||||
}
|
||||
readField(message, jsonValue, field, options, type);
|
||||
}
|
||||
else {
|
||||
let found = false;
|
||||
if ((registry === null || registry === void 0 ? void 0 : registry.findExtension) &&
|
||||
jsonKey.startsWith("[") &&
|
||||
jsonKey.endsWith("]")) {
|
||||
const ext = registry.findExtension(jsonKey.substring(1, jsonKey.length - 1));
|
||||
if (ext && ext.extendee.typeName == type.typeName) {
|
||||
found = true;
|
||||
const [container, get] = (0, extensions_js_1.createExtensionContainer)(ext);
|
||||
readField(container, jsonValue, ext.field, options, ext);
|
||||
// We pass on the options as BinaryReadOptions/BinaryWriteOptions,
|
||||
// so that users can bring their own binary reader and writer factories
|
||||
// if necessary.
|
||||
(0, extension_accessor_js_1.setExtension)(message, ext, get(), options);
|
||||
}
|
||||
}
|
||||
if (!found && !options.ignoreUnknownFields) {
|
||||
throw new Error(`cannot decode message ${type.typeName} from JSON: key "${jsonKey}" is unknown`);
|
||||
}
|
||||
}
|
||||
}
|
||||
return message;
|
||||
},
|
||||
writeMessage(message, options) {
|
||||
const type = message.getType();
|
||||
const json = {};
|
||||
let field;
|
||||
try {
|
||||
for (field of type.fields.byNumber()) {
|
||||
if (!(0, reflect_js_1.isFieldSet)(field, message)) {
|
||||
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
||||
if (field.req) {
|
||||
throw `required field not set`;
|
||||
}
|
||||
if (!options.emitDefaultValues) {
|
||||
continue;
|
||||
}
|
||||
if (!canEmitFieldDefaultValue(field)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
const value = field.oneof
|
||||
? message[field.oneof.localName].value
|
||||
: message[field.localName];
|
||||
const jsonValue = writeField(field, value, options);
|
||||
if (jsonValue !== undefined) {
|
||||
json[options.useProtoFieldName ? field.name : field.jsonName] =
|
||||
jsonValue;
|
||||
}
|
||||
}
|
||||
const registry = options.typeRegistry;
|
||||
if (registry === null || registry === void 0 ? void 0 : registry.findExtensionFor) {
|
||||
for (const uf of type.runtime.bin.listUnknownFields(message)) {
|
||||
const ext = registry.findExtensionFor(type.typeName, uf.no);
|
||||
if (ext && (0, extension_accessor_js_1.hasExtension)(message, ext)) {
|
||||
// We pass on the options as BinaryReadOptions, so that users can bring their own
|
||||
// binary reader factory if necessary.
|
||||
const value = (0, extension_accessor_js_1.getExtension)(message, ext, options);
|
||||
const jsonValue = writeField(ext.field, value, options);
|
||||
if (jsonValue !== undefined) {
|
||||
json[ext.field.jsonName] = jsonValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
const m = field
|
||||
? `cannot encode field ${type.typeName}.${field.name} to JSON`
|
||||
: `cannot encode message ${type.typeName} to JSON`;
|
||||
const r = e instanceof Error ? e.message : String(e);
|
||||
throw new Error(m + (r.length > 0 ? `: ${r}` : ""));
|
||||
}
|
||||
return json;
|
||||
},
|
||||
readScalar(type, json, longType) {
|
||||
// The signature of our internal function has changed. For backwards-
|
||||
// compatibility, we support the old form that is part of the public API
|
||||
// through the interface JsonFormat.
|
||||
return readScalar(type, json, longType !== null && longType !== void 0 ? longType : scalar_js_1.LongType.BIGINT, true);
|
||||
},
|
||||
writeScalar(type, value, emitDefaultValues) {
|
||||
// The signature of our internal function has changed. For backwards-
|
||||
// compatibility, we support the old form that is part of the public API
|
||||
// through the interface JsonFormat.
|
||||
if (value === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
if (emitDefaultValues || (0, scalars_js_2.isScalarZeroValue)(type, value)) {
|
||||
return writeScalar(type, value);
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
debug: debugJsonValue,
|
||||
};
|
||||
}
|
||||
exports.makeJsonFormat = makeJsonFormat;
|
||||
function debugJsonValue(json) {
|
||||
if (json === null) {
|
||||
return "null";
|
||||
}
|
||||
switch (typeof json) {
|
||||
case "object":
|
||||
return Array.isArray(json) ? "array" : "object";
|
||||
case "string":
|
||||
return json.length > 100 ? "string" : `"${json.split('"').join('\\"')}"`;
|
||||
default:
|
||||
return String(json);
|
||||
}
|
||||
}
|
||||
// Read a JSON value for a field.
|
||||
// The "parentType" argument is only used to provide context in errors.
|
||||
function readField(target, jsonValue, field, options, parentType) {
|
||||
let localName = field.localName;
|
||||
if (field.repeated) {
|
||||
(0, assert_js_1.assert)(field.kind != "map");
|
||||
if (jsonValue === null) {
|
||||
return;
|
||||
}
|
||||
if (!Array.isArray(jsonValue)) {
|
||||
throw new Error(`cannot decode field ${parentType.typeName}.${field.name} from JSON: ${debugJsonValue(jsonValue)}`);
|
||||
}
|
||||
const targetArray = target[localName];
|
||||
for (const jsonItem of jsonValue) {
|
||||
if (jsonItem === null) {
|
||||
throw new Error(`cannot decode field ${parentType.typeName}.${field.name} from JSON: ${debugJsonValue(jsonItem)}`);
|
||||
}
|
||||
switch (field.kind) {
|
||||
case "message":
|
||||
targetArray.push(field.T.fromJson(jsonItem, options));
|
||||
break;
|
||||
case "enum":
|
||||
const enumValue = readEnum(field.T, jsonItem, options.ignoreUnknownFields, true);
|
||||
if (enumValue !== tokenIgnoredUnknownEnum) {
|
||||
targetArray.push(enumValue);
|
||||
}
|
||||
break;
|
||||
case "scalar":
|
||||
try {
|
||||
targetArray.push(readScalar(field.T, jsonItem, field.L, true));
|
||||
}
|
||||
catch (e) {
|
||||
let m = `cannot decode field ${parentType.typeName}.${field.name} from JSON: ${debugJsonValue(jsonItem)}`;
|
||||
if (e instanceof Error && e.message.length > 0) {
|
||||
m += `: ${e.message}`;
|
||||
}
|
||||
throw new Error(m);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (field.kind == "map") {
|
||||
if (jsonValue === null) {
|
||||
return;
|
||||
}
|
||||
if (typeof jsonValue != "object" || Array.isArray(jsonValue)) {
|
||||
throw new Error(`cannot decode field ${parentType.typeName}.${field.name} from JSON: ${debugJsonValue(jsonValue)}`);
|
||||
}
|
||||
const targetMap = target[localName];
|
||||
for (const [jsonMapKey, jsonMapValue] of Object.entries(jsonValue)) {
|
||||
if (jsonMapValue === null) {
|
||||
throw new Error(`cannot decode field ${parentType.typeName}.${field.name} from JSON: map value null`);
|
||||
}
|
||||
let key;
|
||||
try {
|
||||
key = readMapKey(field.K, jsonMapKey);
|
||||
}
|
||||
catch (e) {
|
||||
let m = `cannot decode map key for field ${parentType.typeName}.${field.name} from JSON: ${debugJsonValue(jsonValue)}`;
|
||||
if (e instanceof Error && e.message.length > 0) {
|
||||
m += `: ${e.message}`;
|
||||
}
|
||||
throw new Error(m);
|
||||
}
|
||||
switch (field.V.kind) {
|
||||
case "message":
|
||||
targetMap[key] = field.V.T.fromJson(jsonMapValue, options);
|
||||
break;
|
||||
case "enum":
|
||||
const enumValue = readEnum(field.V.T, jsonMapValue, options.ignoreUnknownFields, true);
|
||||
if (enumValue !== tokenIgnoredUnknownEnum) {
|
||||
targetMap[key] = enumValue;
|
||||
}
|
||||
break;
|
||||
case "scalar":
|
||||
try {
|
||||
targetMap[key] = readScalar(field.V.T, jsonMapValue, scalar_js_1.LongType.BIGINT, true);
|
||||
}
|
||||
catch (e) {
|
||||
let m = `cannot decode map value for field ${parentType.typeName}.${field.name} from JSON: ${debugJsonValue(jsonValue)}`;
|
||||
if (e instanceof Error && e.message.length > 0) {
|
||||
m += `: ${e.message}`;
|
||||
}
|
||||
throw new Error(m);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (field.oneof) {
|
||||
target = target[field.oneof.localName] = { case: localName };
|
||||
localName = "value";
|
||||
}
|
||||
switch (field.kind) {
|
||||
case "message":
|
||||
const messageType = field.T;
|
||||
if (jsonValue === null &&
|
||||
messageType.typeName != "google.protobuf.Value") {
|
||||
return;
|
||||
}
|
||||
let currentValue = target[localName];
|
||||
if ((0, is_message_js_1.isMessage)(currentValue)) {
|
||||
currentValue.fromJson(jsonValue, options);
|
||||
}
|
||||
else {
|
||||
target[localName] = currentValue = messageType.fromJson(jsonValue, options);
|
||||
if (messageType.fieldWrapper && !field.oneof) {
|
||||
target[localName] =
|
||||
messageType.fieldWrapper.unwrapField(currentValue);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "enum":
|
||||
const enumValue = readEnum(field.T, jsonValue, options.ignoreUnknownFields, false);
|
||||
switch (enumValue) {
|
||||
case tokenNull:
|
||||
(0, reflect_js_1.clearField)(field, target);
|
||||
break;
|
||||
case tokenIgnoredUnknownEnum:
|
||||
break;
|
||||
default:
|
||||
target[localName] = enumValue;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case "scalar":
|
||||
try {
|
||||
const scalarValue = readScalar(field.T, jsonValue, field.L, false);
|
||||
switch (scalarValue) {
|
||||
case tokenNull:
|
||||
(0, reflect_js_1.clearField)(field, target);
|
||||
break;
|
||||
default:
|
||||
target[localName] = scalarValue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
let m = `cannot decode field ${parentType.typeName}.${field.name} from JSON: ${debugJsonValue(jsonValue)}`;
|
||||
if (e instanceof Error && e.message.length > 0) {
|
||||
m += `: ${e.message}`;
|
||||
}
|
||||
throw new Error(m);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
function readMapKey(type, json) {
|
||||
if (type === scalar_js_1.ScalarType.BOOL) {
|
||||
// eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check
|
||||
switch (json) {
|
||||
case "true":
|
||||
json = true;
|
||||
break;
|
||||
case "false":
|
||||
json = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return readScalar(type, json, scalar_js_1.LongType.BIGINT, true).toString();
|
||||
}
|
||||
function readScalar(type, json, longType, nullAsZeroValue) {
|
||||
if (json === null) {
|
||||
if (nullAsZeroValue) {
|
||||
return (0, scalars_js_1.scalarZeroValue)(type, longType);
|
||||
}
|
||||
return tokenNull;
|
||||
}
|
||||
// every valid case in the switch below returns, and every fall
|
||||
// through is regarded as a failure.
|
||||
switch (type) {
|
||||
// float, double: JSON value will be a number or one of the special string values "NaN", "Infinity", and "-Infinity".
|
||||
// Either numbers or strings are accepted. Exponent notation is also accepted.
|
||||
case scalar_js_1.ScalarType.DOUBLE:
|
||||
case scalar_js_1.ScalarType.FLOAT:
|
||||
if (json === "NaN")
|
||||
return Number.NaN;
|
||||
if (json === "Infinity")
|
||||
return Number.POSITIVE_INFINITY;
|
||||
if (json === "-Infinity")
|
||||
return Number.NEGATIVE_INFINITY;
|
||||
if (json === "") {
|
||||
// empty string is not a number
|
||||
break;
|
||||
}
|
||||
if (typeof json == "string" && json.trim().length !== json.length) {
|
||||
// extra whitespace
|
||||
break;
|
||||
}
|
||||
if (typeof json != "string" && typeof json != "number") {
|
||||
break;
|
||||
}
|
||||
const float = Number(json);
|
||||
if (Number.isNaN(float)) {
|
||||
// not a number
|
||||
break;
|
||||
}
|
||||
if (!Number.isFinite(float)) {
|
||||
// infinity and -infinity are handled by string representation above, so this is an error
|
||||
break;
|
||||
}
|
||||
if (type == scalar_js_1.ScalarType.FLOAT)
|
||||
(0, assert_js_1.assertFloat32)(float);
|
||||
return float;
|
||||
// int32, fixed32, uint32: JSON value will be a decimal number. Either numbers or strings are accepted.
|
||||
case scalar_js_1.ScalarType.INT32:
|
||||
case scalar_js_1.ScalarType.FIXED32:
|
||||
case scalar_js_1.ScalarType.SFIXED32:
|
||||
case scalar_js_1.ScalarType.SINT32:
|
||||
case scalar_js_1.ScalarType.UINT32:
|
||||
let int32;
|
||||
if (typeof json == "number")
|
||||
int32 = json;
|
||||
else if (typeof json == "string" && json.length > 0) {
|
||||
if (json.trim().length === json.length)
|
||||
int32 = Number(json);
|
||||
}
|
||||
if (int32 === undefined)
|
||||
break;
|
||||
if (type == scalar_js_1.ScalarType.UINT32 || type == scalar_js_1.ScalarType.FIXED32)
|
||||
(0, assert_js_1.assertUInt32)(int32);
|
||||
else
|
||||
(0, assert_js_1.assertInt32)(int32);
|
||||
return int32;
|
||||
// int64, fixed64, uint64: JSON value will be a decimal string. Either numbers or strings are accepted.
|
||||
case scalar_js_1.ScalarType.INT64:
|
||||
case scalar_js_1.ScalarType.SFIXED64:
|
||||
case scalar_js_1.ScalarType.SINT64:
|
||||
if (typeof json != "number" && typeof json != "string")
|
||||
break;
|
||||
const long = proto_int64_js_1.protoInt64.parse(json);
|
||||
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
||||
return longType ? long.toString() : long;
|
||||
case scalar_js_1.ScalarType.FIXED64:
|
||||
case scalar_js_1.ScalarType.UINT64:
|
||||
if (typeof json != "number" && typeof json != "string")
|
||||
break;
|
||||
const uLong = proto_int64_js_1.protoInt64.uParse(json);
|
||||
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
||||
return longType ? uLong.toString() : uLong;
|
||||
// bool:
|
||||
case scalar_js_1.ScalarType.BOOL:
|
||||
if (typeof json !== "boolean")
|
||||
break;
|
||||
return json;
|
||||
// string:
|
||||
case scalar_js_1.ScalarType.STRING:
|
||||
if (typeof json !== "string") {
|
||||
break;
|
||||
}
|
||||
// A string must always contain UTF-8 encoded or 7-bit ASCII.
|
||||
// We validate with encodeURIComponent, which appears to be the fastest widely available option.
|
||||
try {
|
||||
encodeURIComponent(json);
|
||||
}
|
||||
catch (e) {
|
||||
throw new Error("invalid UTF8");
|
||||
}
|
||||
return json;
|
||||
// bytes: JSON value will be the data encoded as a string using standard base64 encoding with paddings.
|
||||
// Either standard or URL-safe base64 encoding with/without paddings are accepted.
|
||||
case scalar_js_1.ScalarType.BYTES:
|
||||
if (json === "")
|
||||
return new Uint8Array(0);
|
||||
if (typeof json !== "string")
|
||||
break;
|
||||
return proto_base64_js_1.protoBase64.dec(json);
|
||||
}
|
||||
throw new Error();
|
||||
}
|
||||
function readEnum(type, json, ignoreUnknownFields, nullAsZeroValue) {
|
||||
if (json === null) {
|
||||
if (type.typeName == "google.protobuf.NullValue") {
|
||||
return 0; // google.protobuf.NullValue.NULL_VALUE = 0
|
||||
}
|
||||
return nullAsZeroValue ? type.values[0].no : tokenNull;
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check
|
||||
switch (typeof json) {
|
||||
case "number":
|
||||
if (Number.isInteger(json)) {
|
||||
return json;
|
||||
}
|
||||
break;
|
||||
case "string":
|
||||
const value = type.findName(json);
|
||||
if (value !== undefined) {
|
||||
return value.no;
|
||||
}
|
||||
if (ignoreUnknownFields) {
|
||||
return tokenIgnoredUnknownEnum;
|
||||
}
|
||||
break;
|
||||
}
|
||||
throw new Error(`cannot decode enum ${type.typeName} from JSON: ${debugJsonValue(json)}`);
|
||||
}
|
||||
// Decide whether an unset field should be emitted with JSON write option `emitDefaultValues`
|
||||
function canEmitFieldDefaultValue(field) {
|
||||
if (field.repeated || field.kind == "map") {
|
||||
// maps are {}, repeated fields are []
|
||||
return true;
|
||||
}
|
||||
if (field.oneof) {
|
||||
// oneof fields are never emitted
|
||||
return false;
|
||||
}
|
||||
if (field.kind == "message") {
|
||||
// singular message field are allowed to emit JSON null, but we do not
|
||||
return false;
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
||||
if (field.opt || field.req) {
|
||||
// the field uses explicit presence, so we cannot emit a zero value
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
function writeField(field, value, options) {
|
||||
if (field.kind == "map") {
|
||||
(0, assert_js_1.assert)(typeof value == "object" && value != null);
|
||||
const jsonObj = {};
|
||||
const entries = Object.entries(value);
|
||||
switch (field.V.kind) {
|
||||
case "scalar":
|
||||
for (const [entryKey, entryValue] of entries) {
|
||||
jsonObj[entryKey.toString()] = writeScalar(field.V.T, entryValue); // JSON standard allows only (double quoted) string as property key
|
||||
}
|
||||
break;
|
||||
case "message":
|
||||
for (const [entryKey, entryValue] of entries) {
|
||||
// JSON standard allows only (double quoted) string as property key
|
||||
jsonObj[entryKey.toString()] = entryValue.toJson(options);
|
||||
}
|
||||
break;
|
||||
case "enum":
|
||||
const enumType = field.V.T;
|
||||
for (const [entryKey, entryValue] of entries) {
|
||||
// JSON standard allows only (double quoted) string as property key
|
||||
jsonObj[entryKey.toString()] = writeEnum(enumType, entryValue, options.enumAsInteger);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return options.emitDefaultValues || entries.length > 0
|
||||
? jsonObj
|
||||
: undefined;
|
||||
}
|
||||
if (field.repeated) {
|
||||
(0, assert_js_1.assert)(Array.isArray(value));
|
||||
const jsonArr = [];
|
||||
switch (field.kind) {
|
||||
case "scalar":
|
||||
for (let i = 0; i < value.length; i++) {
|
||||
jsonArr.push(writeScalar(field.T, value[i]));
|
||||
}
|
||||
break;
|
||||
case "enum":
|
||||
for (let i = 0; i < value.length; i++) {
|
||||
jsonArr.push(writeEnum(field.T, value[i], options.enumAsInteger));
|
||||
}
|
||||
break;
|
||||
case "message":
|
||||
for (let i = 0; i < value.length; i++) {
|
||||
jsonArr.push(value[i].toJson(options));
|
||||
}
|
||||
break;
|
||||
}
|
||||
return options.emitDefaultValues || jsonArr.length > 0
|
||||
? jsonArr
|
||||
: undefined;
|
||||
}
|
||||
switch (field.kind) {
|
||||
case "scalar":
|
||||
return writeScalar(field.T, value);
|
||||
case "enum":
|
||||
return writeEnum(field.T, value, options.enumAsInteger);
|
||||
case "message":
|
||||
return (0, field_wrapper_js_1.wrapField)(field.T, value).toJson(options);
|
||||
}
|
||||
}
|
||||
function writeEnum(type, value, enumAsInteger) {
|
||||
var _a;
|
||||
(0, assert_js_1.assert)(typeof value == "number");
|
||||
if (type.typeName == "google.protobuf.NullValue") {
|
||||
return null;
|
||||
}
|
||||
if (enumAsInteger) {
|
||||
return value;
|
||||
}
|
||||
const val = type.findNumber(value);
|
||||
return (_a = val === null || val === void 0 ? void 0 : val.name) !== null && _a !== void 0 ? _a : value; // if we don't know the enum value, just return the number
|
||||
}
|
||||
function writeScalar(type, value) {
|
||||
switch (type) {
|
||||
// int32, fixed32, uint32: JSON value will be a decimal number. Either numbers or strings are accepted.
|
||||
case scalar_js_1.ScalarType.INT32:
|
||||
case scalar_js_1.ScalarType.SFIXED32:
|
||||
case scalar_js_1.ScalarType.SINT32:
|
||||
case scalar_js_1.ScalarType.FIXED32:
|
||||
case scalar_js_1.ScalarType.UINT32:
|
||||
(0, assert_js_1.assert)(typeof value == "number");
|
||||
return value;
|
||||
// float, double: JSON value will be a number or one of the special string values "NaN", "Infinity", and "-Infinity".
|
||||
// Either numbers or strings are accepted. Exponent notation is also accepted.
|
||||
case scalar_js_1.ScalarType.FLOAT:
|
||||
// assertFloat32(value);
|
||||
case scalar_js_1.ScalarType.DOUBLE: // eslint-disable-line no-fallthrough
|
||||
(0, assert_js_1.assert)(typeof value == "number");
|
||||
if (Number.isNaN(value))
|
||||
return "NaN";
|
||||
if (value === Number.POSITIVE_INFINITY)
|
||||
return "Infinity";
|
||||
if (value === Number.NEGATIVE_INFINITY)
|
||||
return "-Infinity";
|
||||
return value;
|
||||
// string:
|
||||
case scalar_js_1.ScalarType.STRING:
|
||||
(0, assert_js_1.assert)(typeof value == "string");
|
||||
return value;
|
||||
// bool:
|
||||
case scalar_js_1.ScalarType.BOOL:
|
||||
(0, assert_js_1.assert)(typeof value == "boolean");
|
||||
return value;
|
||||
// JSON value will be a decimal string. Either numbers or strings are accepted.
|
||||
case scalar_js_1.ScalarType.UINT64:
|
||||
case scalar_js_1.ScalarType.FIXED64:
|
||||
case scalar_js_1.ScalarType.INT64:
|
||||
case scalar_js_1.ScalarType.SFIXED64:
|
||||
case scalar_js_1.ScalarType.SINT64:
|
||||
(0, assert_js_1.assert)(typeof value == "bigint" ||
|
||||
typeof value == "string" ||
|
||||
typeof value == "number");
|
||||
return value.toString();
|
||||
// bytes: JSON value will be the data encoded as a string using standard base64 encoding with paddings.
|
||||
// Either standard or URL-safe base64 encoding with/without paddings are accepted.
|
||||
case scalar_js_1.ScalarType.BYTES:
|
||||
(0, assert_js_1.assert)(value instanceof Uint8Array);
|
||||
return proto_base64_js_1.protoBase64.enc(value);
|
||||
}
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
import { Message } from "../message.js";
|
||||
import type { AnyMessage } from "../message.js";
|
||||
import type { FieldListSource } from "./field-list.js";
|
||||
import type { MessageType } from "../message-type.js";
|
||||
import type { ProtoRuntime } from "./proto-runtime.js";
|
||||
/**
|
||||
* Create a new message type using the given runtime.
|
||||
*/
|
||||
export declare function makeMessageType<T extends Message<T> = AnyMessage>(runtime: ProtoRuntime, typeName: string, fields: FieldListSource, opt?: {
|
||||
/**
|
||||
* localName is the "name" property of the constructed function.
|
||||
* It is useful in stack traces, debuggers and test frameworks,
|
||||
* but has no other implications.
|
||||
*
|
||||
* If omitted, the last part of the typeName is used.
|
||||
*/
|
||||
localName?: string;
|
||||
}): MessageType<T>;
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
"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.makeMessageType = void 0;
|
||||
const message_js_1 = require("../message.js");
|
||||
/**
|
||||
* Create a new message type using the given runtime.
|
||||
*/
|
||||
function makeMessageType(runtime, typeName, fields, opt) {
|
||||
var _a;
|
||||
const localName = (_a = opt === null || opt === void 0 ? void 0 : opt.localName) !== null && _a !== void 0 ? _a : typeName.substring(typeName.lastIndexOf(".") + 1);
|
||||
const type = {
|
||||
[localName]: function (data) {
|
||||
runtime.util.initFields(this);
|
||||
runtime.util.initPartial(data, this);
|
||||
},
|
||||
}[localName];
|
||||
Object.setPrototypeOf(type.prototype, new message_js_1.Message());
|
||||
Object.assign(type, {
|
||||
runtime,
|
||||
typeName,
|
||||
fields: runtime.util.newFieldList(fields),
|
||||
fromBinary(bytes, options) {
|
||||
return new type().fromBinary(bytes, options);
|
||||
},
|
||||
fromJson(jsonValue, options) {
|
||||
return new type().fromJson(jsonValue, options);
|
||||
},
|
||||
fromJsonString(jsonString, options) {
|
||||
return new type().fromJsonString(jsonString, options);
|
||||
},
|
||||
equals(a, b) {
|
||||
return runtime.util.equals(type, a, b);
|
||||
},
|
||||
});
|
||||
return type;
|
||||
}
|
||||
exports.makeMessageType = makeMessageType;
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
import type { DescEnum, DescEnumValue, DescExtension, DescField, DescMessage, DescService } from "../descriptor-set.js";
|
||||
import type { DescMethod, DescOneof } from "../descriptor-set.js";
|
||||
/**
|
||||
* Returns the name of a protobuf element in generated code.
|
||||
*
|
||||
* Field names - including oneofs - are converted to lowerCamelCase. For
|
||||
* messages, enumerations and services, the package name is stripped from
|
||||
* the type name. For nested messages and enumerations, the names are joined
|
||||
* with an underscore. For methods, the first character is made lowercase.
|
||||
*/
|
||||
export declare function localName(desc: DescEnum | DescEnumValue | DescMessage | DescExtension | DescOneof | DescField | DescService | DescMethod): string;
|
||||
/**
|
||||
* Returns the name of a field in generated code.
|
||||
*/
|
||||
export declare function localFieldName(protoName: string, inOneof: boolean): string;
|
||||
/**
|
||||
* Returns the name of a oneof group in generated code.
|
||||
*/
|
||||
export declare function localOneofName(protoName: string): string;
|
||||
/**
|
||||
* Returns the JSON name for a protobuf field, exactly like protoc does.
|
||||
*/
|
||||
export declare const fieldJsonName: typeof protoCamelCase;
|
||||
/**
|
||||
* Finds a prefix shared by enum values, for example `MY_ENUM_` for
|
||||
* `enum MyEnum {MY_ENUM_A=0; MY_ENUM_B=1;}`.
|
||||
*/
|
||||
export declare function findEnumSharedPrefix(enumName: string, valueNames: string[]): string | undefined;
|
||||
/**
|
||||
* Converts snake_case to protoCamelCase according to the convention
|
||||
* used by protoc to convert a field name to a JSON name.
|
||||
*/
|
||||
declare function protoCamelCase(snakeCase: string): string;
|
||||
/**
|
||||
* Names that cannot be used for object properties because they are reserved
|
||||
* by built-in JavaScript properties.
|
||||
*/
|
||||
export declare const safeObjectProperty: (name: string) => string;
|
||||
/**
|
||||
* Names that can be used for identifiers or class properties
|
||||
*/
|
||||
export declare const safeIdentifier: (name: string) => string;
|
||||
export {};
|
||||
+278
@@ -0,0 +1,278 @@
|
||||
"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.safeIdentifier = exports.safeObjectProperty = exports.findEnumSharedPrefix = exports.fieldJsonName = exports.localOneofName = exports.localFieldName = exports.localName = void 0;
|
||||
/**
|
||||
* Returns the name of a protobuf element in generated code.
|
||||
*
|
||||
* Field names - including oneofs - are converted to lowerCamelCase. For
|
||||
* messages, enumerations and services, the package name is stripped from
|
||||
* the type name. For nested messages and enumerations, the names are joined
|
||||
* with an underscore. For methods, the first character is made lowercase.
|
||||
*/
|
||||
function localName(desc) {
|
||||
switch (desc.kind) {
|
||||
case "field":
|
||||
return localFieldName(desc.name, desc.oneof !== undefined);
|
||||
case "oneof":
|
||||
return localOneofName(desc.name);
|
||||
case "enum":
|
||||
case "message":
|
||||
case "service":
|
||||
case "extension": {
|
||||
const pkg = desc.file.proto.package;
|
||||
const offset = pkg === undefined ? 0 : pkg.length + 1;
|
||||
const name = desc.typeName.substring(offset).replace(/\./g, "_");
|
||||
// For services, we only care about safe identifiers, not safe object properties,
|
||||
// but we have shipped v1 with a bug that respected object properties, and we
|
||||
// do not want to introduce a breaking change, so we continue to escape for
|
||||
// safe object properties.
|
||||
// See https://github.com/bufbuild/protobuf-es/pull/391
|
||||
return (0, exports.safeObjectProperty)((0, exports.safeIdentifier)(name));
|
||||
}
|
||||
case "enum_value": {
|
||||
let name = desc.name;
|
||||
const sharedPrefix = desc.parent.sharedPrefix;
|
||||
if (sharedPrefix !== undefined) {
|
||||
name = name.substring(sharedPrefix.length);
|
||||
}
|
||||
return (0, exports.safeObjectProperty)(name);
|
||||
}
|
||||
case "rpc": {
|
||||
let name = desc.name;
|
||||
if (name.length == 0) {
|
||||
return name;
|
||||
}
|
||||
name = name[0].toLowerCase() + name.substring(1);
|
||||
return (0, exports.safeObjectProperty)(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.localName = localName;
|
||||
/**
|
||||
* Returns the name of a field in generated code.
|
||||
*/
|
||||
function localFieldName(protoName, inOneof) {
|
||||
const name = protoCamelCase(protoName);
|
||||
if (inOneof) {
|
||||
// oneof member names are not properties, but values of the `case` property.
|
||||
return name;
|
||||
}
|
||||
return (0, exports.safeObjectProperty)(safeMessageProperty(name));
|
||||
}
|
||||
exports.localFieldName = localFieldName;
|
||||
/**
|
||||
* Returns the name of a oneof group in generated code.
|
||||
*/
|
||||
function localOneofName(protoName) {
|
||||
return localFieldName(protoName, false);
|
||||
}
|
||||
exports.localOneofName = localOneofName;
|
||||
/**
|
||||
* Returns the JSON name for a protobuf field, exactly like protoc does.
|
||||
*/
|
||||
exports.fieldJsonName = protoCamelCase;
|
||||
/**
|
||||
* Finds a prefix shared by enum values, for example `MY_ENUM_` for
|
||||
* `enum MyEnum {MY_ENUM_A=0; MY_ENUM_B=1;}`.
|
||||
*/
|
||||
function findEnumSharedPrefix(enumName, valueNames) {
|
||||
const prefix = camelToSnakeCase(enumName) + "_";
|
||||
for (const name of valueNames) {
|
||||
if (!name.toLowerCase().startsWith(prefix)) {
|
||||
return undefined;
|
||||
}
|
||||
const shortName = name.substring(prefix.length);
|
||||
if (shortName.length == 0) {
|
||||
return undefined;
|
||||
}
|
||||
if (/^\d/.test(shortName)) {
|
||||
// identifiers must not start with numbers
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
return prefix;
|
||||
}
|
||||
exports.findEnumSharedPrefix = findEnumSharedPrefix;
|
||||
/**
|
||||
* Converts lowerCamelCase or UpperCamelCase into lower_snake_case.
|
||||
* This is used to find shared prefixes in an enum.
|
||||
*/
|
||||
function camelToSnakeCase(camel) {
|
||||
return (camel.substring(0, 1) + camel.substring(1).replace(/[A-Z]/g, (c) => "_" + c)).toLowerCase();
|
||||
}
|
||||
/**
|
||||
* Converts snake_case to protoCamelCase according to the convention
|
||||
* used by protoc to convert a field name to a JSON name.
|
||||
*/
|
||||
function protoCamelCase(snakeCase) {
|
||||
let capNext = false;
|
||||
const b = [];
|
||||
for (let i = 0; i < snakeCase.length; i++) {
|
||||
let c = snakeCase.charAt(i);
|
||||
switch (c) {
|
||||
case "_":
|
||||
capNext = true;
|
||||
break;
|
||||
case "0":
|
||||
case "1":
|
||||
case "2":
|
||||
case "3":
|
||||
case "4":
|
||||
case "5":
|
||||
case "6":
|
||||
case "7":
|
||||
case "8":
|
||||
case "9":
|
||||
b.push(c);
|
||||
capNext = false;
|
||||
break;
|
||||
default:
|
||||
if (capNext) {
|
||||
capNext = false;
|
||||
c = c.toUpperCase();
|
||||
}
|
||||
b.push(c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return b.join("");
|
||||
}
|
||||
/**
|
||||
* Names that cannot be used for identifiers, such as class names,
|
||||
* but _can_ be used for object properties.
|
||||
*/
|
||||
const reservedIdentifiers = new Set([
|
||||
// ECMAScript 2015 keywords
|
||||
"break",
|
||||
"case",
|
||||
"catch",
|
||||
"class",
|
||||
"const",
|
||||
"continue",
|
||||
"debugger",
|
||||
"default",
|
||||
"delete",
|
||||
"do",
|
||||
"else",
|
||||
"export",
|
||||
"extends",
|
||||
"false",
|
||||
"finally",
|
||||
"for",
|
||||
"function",
|
||||
"if",
|
||||
"import",
|
||||
"in",
|
||||
"instanceof",
|
||||
"new",
|
||||
"null",
|
||||
"return",
|
||||
"super",
|
||||
"switch",
|
||||
"this",
|
||||
"throw",
|
||||
"true",
|
||||
"try",
|
||||
"typeof",
|
||||
"var",
|
||||
"void",
|
||||
"while",
|
||||
"with",
|
||||
"yield",
|
||||
// ECMAScript 2015 future reserved keywords
|
||||
"enum",
|
||||
"implements",
|
||||
"interface",
|
||||
"let",
|
||||
"package",
|
||||
"private",
|
||||
"protected",
|
||||
"public",
|
||||
"static",
|
||||
// Class name cannot be 'Object' when targeting ES5 with module CommonJS
|
||||
"Object",
|
||||
// TypeScript keywords that cannot be used for types (as opposed to variables)
|
||||
"bigint",
|
||||
"number",
|
||||
"boolean",
|
||||
"string",
|
||||
"object",
|
||||
// Identifiers reserved for the runtime, so we can generate legible code
|
||||
"globalThis",
|
||||
"Uint8Array",
|
||||
"Partial",
|
||||
]);
|
||||
/**
|
||||
* Names that cannot be used for object properties because they are reserved
|
||||
* by built-in JavaScript properties.
|
||||
*/
|
||||
const reservedObjectProperties = new Set([
|
||||
// names reserved by JavaScript
|
||||
"constructor",
|
||||
"toString",
|
||||
"toJSON",
|
||||
"valueOf",
|
||||
]);
|
||||
/**
|
||||
* Names that cannot be used for object properties because they are reserved
|
||||
* by the runtime.
|
||||
*/
|
||||
const reservedMessageProperties = new Set([
|
||||
// names reserved by the runtime
|
||||
"getType",
|
||||
"clone",
|
||||
"equals",
|
||||
"fromBinary",
|
||||
"fromJson",
|
||||
"fromJsonString",
|
||||
"toBinary",
|
||||
"toJson",
|
||||
"toJsonString",
|
||||
// names reserved by the runtime for the future
|
||||
"toObject",
|
||||
]);
|
||||
const fallback = (name) => `${name}$`;
|
||||
/**
|
||||
* Will wrap names that are Object prototype properties or names reserved
|
||||
* for `Message`s.
|
||||
*/
|
||||
const safeMessageProperty = (name) => {
|
||||
if (reservedMessageProperties.has(name)) {
|
||||
return fallback(name);
|
||||
}
|
||||
return name;
|
||||
};
|
||||
/**
|
||||
* Names that cannot be used for object properties because they are reserved
|
||||
* by built-in JavaScript properties.
|
||||
*/
|
||||
const safeObjectProperty = (name) => {
|
||||
if (reservedObjectProperties.has(name)) {
|
||||
return fallback(name);
|
||||
}
|
||||
return name;
|
||||
};
|
||||
exports.safeObjectProperty = safeObjectProperty;
|
||||
/**
|
||||
* Names that can be used for identifiers or class properties
|
||||
*/
|
||||
const safeIdentifier = (name) => {
|
||||
if (reservedIdentifiers.has(name)) {
|
||||
return fallback(name);
|
||||
}
|
||||
return name;
|
||||
};
|
||||
exports.safeIdentifier = safeIdentifier;
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
import type { JsonValue } from "../json-format.js";
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export type OptionsMap = {
|
||||
readonly [extensionName: string]: JsonValue;
|
||||
};
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
"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 });
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
import type { JsonFormat } from "../json-format.js";
|
||||
import type { BinaryFormat } from "../binary-format.js";
|
||||
import type { AnyMessage } from "../message.js";
|
||||
import type { Message } from "../message.js";
|
||||
import type { EnumType, EnumValueInfo } from "../enum.js";
|
||||
import type { MessageType } from "../message-type.js";
|
||||
import type { FieldListSource } from "./field-list.js";
|
||||
import type { EnumObject } from "./enum.js";
|
||||
import type { Util } from "./util.js";
|
||||
import type { Extension } from "../extension.js";
|
||||
import type { ExtensionFieldSource } from "./extensions.js";
|
||||
/**
|
||||
* A facade that provides serialization and other internal functionality.
|
||||
*/
|
||||
export interface ProtoRuntime {
|
||||
readonly syntax: string;
|
||||
readonly json: JsonFormat;
|
||||
readonly bin: BinaryFormat;
|
||||
readonly util: Util;
|
||||
/**
|
||||
* Create a message type at runtime, without generating code.
|
||||
*/
|
||||
makeMessageType<T extends Message<T> = AnyMessage>(typeName: string, fields: FieldListSource, opt?: {
|
||||
localName?: string;
|
||||
}): MessageType<T>;
|
||||
/**
|
||||
* Create an enum object at runtime, without generating code.
|
||||
*
|
||||
* The object conforms to TypeScript enums, and comes with
|
||||
* mapping from name to value, and from value to name.
|
||||
*
|
||||
* The type name and other reflection information is accessible
|
||||
* via getEnumType().
|
||||
*/
|
||||
makeEnum(typeName: string, values: (EnumValueInfo | Omit<EnumValueInfo, "localName">)[], opt?: {}): EnumObject;
|
||||
/**
|
||||
* Create an enum type at runtime, without generating code.
|
||||
* Note that this only creates the reflection information, not an
|
||||
* actual enum object.
|
||||
*/
|
||||
makeEnumType(typeName: string, values: (EnumValueInfo | Omit<EnumValueInfo, "localName">)[], opt?: {}): EnumType;
|
||||
/**
|
||||
* Get reflection information - the EnumType - from an enum object.
|
||||
* If this function is called on something other than a generated
|
||||
* enum, or an enum constructed with makeEnum(), it raises an error.
|
||||
*/
|
||||
getEnumType(enumObject: EnumObject): EnumType;
|
||||
/**
|
||||
* Create an extension at runtime, without generating code.
|
||||
*/
|
||||
makeExtension<E extends Message<E> = AnyMessage, V = unknown>(typeName: string, extendee: MessageType<E>, field: ExtensionFieldSource): Extension<E, V>;
|
||||
}
|
||||
export declare function makeProtoRuntime(syntax: string, newFieldList: Util["newFieldList"], initFields: Util["initFields"]): ProtoRuntime;
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
"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.makeProtoRuntime = void 0;
|
||||
const enum_js_1 = require("./enum.js");
|
||||
const message_type_js_1 = require("./message-type.js");
|
||||
const extensions_js_1 = require("./extensions.js");
|
||||
const json_format_js_1 = require("./json-format.js");
|
||||
const binary_format_js_1 = require("./binary-format.js");
|
||||
const util_common_js_1 = require("./util-common.js");
|
||||
function makeProtoRuntime(syntax, newFieldList, initFields) {
|
||||
return {
|
||||
syntax,
|
||||
json: (0, json_format_js_1.makeJsonFormat)(),
|
||||
bin: (0, binary_format_js_1.makeBinaryFormat)(),
|
||||
util: Object.assign(Object.assign({}, (0, util_common_js_1.makeUtilCommon)()), { newFieldList,
|
||||
initFields }),
|
||||
makeMessageType(typeName, fields, opt) {
|
||||
return (0, message_type_js_1.makeMessageType)(this, typeName, fields, opt);
|
||||
},
|
||||
makeEnum: enum_js_1.makeEnum,
|
||||
makeEnumType: enum_js_1.makeEnumType,
|
||||
getEnumType: enum_js_1.getEnumType,
|
||||
makeExtension(typeName, extendee, field) {
|
||||
return (0, extensions_js_1.makeExtension)(this, typeName, extendee, field);
|
||||
},
|
||||
};
|
||||
}
|
||||
exports.makeProtoRuntime = makeProtoRuntime;
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
import type { FieldInfo } from "../field.js";
|
||||
/**
|
||||
* Returns true if the field is set.
|
||||
*/
|
||||
export declare function isFieldSet(field: FieldInfo, target: Record<string, any>): boolean;
|
||||
/**
|
||||
* Resets the field, so that isFieldSet() will return false.
|
||||
*/
|
||||
export declare function clearField(field: FieldInfo, target: Record<string, any>): void;
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
"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.clearField = exports.isFieldSet = void 0;
|
||||
const scalars_js_1 = require("./scalars.js");
|
||||
/**
|
||||
* Returns true if the field is set.
|
||||
*/
|
||||
function isFieldSet(field, target) {
|
||||
const localName = field.localName;
|
||||
if (field.repeated) {
|
||||
return target[localName].length > 0;
|
||||
}
|
||||
if (field.oneof) {
|
||||
return target[field.oneof.localName].case === localName; // eslint-disable-line @typescript-eslint/no-unsafe-member-access
|
||||
}
|
||||
switch (field.kind) {
|
||||
case "enum":
|
||||
case "scalar":
|
||||
if (field.opt || field.req) {
|
||||
// explicit presence
|
||||
return target[localName] !== undefined;
|
||||
}
|
||||
// implicit presence
|
||||
if (field.kind == "enum") {
|
||||
return target[localName] !== field.T.values[0].no;
|
||||
}
|
||||
return !(0, scalars_js_1.isScalarZeroValue)(field.T, target[localName]);
|
||||
case "message":
|
||||
return target[localName] !== undefined;
|
||||
case "map":
|
||||
return Object.keys(target[localName]).length > 0; // eslint-disable-line @typescript-eslint/no-unsafe-argument
|
||||
}
|
||||
}
|
||||
exports.isFieldSet = isFieldSet;
|
||||
/**
|
||||
* Resets the field, so that isFieldSet() will return false.
|
||||
*/
|
||||
function clearField(field, target) {
|
||||
const localName = field.localName;
|
||||
const implicitPresence = !field.opt && !field.req;
|
||||
if (field.repeated) {
|
||||
target[localName] = [];
|
||||
}
|
||||
else if (field.oneof) {
|
||||
target[field.oneof.localName] = { case: undefined };
|
||||
}
|
||||
else {
|
||||
switch (field.kind) {
|
||||
case "map":
|
||||
target[localName] = {};
|
||||
break;
|
||||
case "enum":
|
||||
target[localName] = implicitPresence ? field.T.values[0].no : undefined;
|
||||
break;
|
||||
case "scalar":
|
||||
target[localName] = implicitPresence
|
||||
? (0, scalars_js_1.scalarZeroValue)(field.T, field.L)
|
||||
: undefined;
|
||||
break;
|
||||
case "message":
|
||||
target[localName] = undefined;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.clearField = clearField;
|
||||
+102
@@ -0,0 +1,102 @@
|
||||
import type { DescField, DescMessage, DescOneof } from "../descriptor-set.js";
|
||||
type DescWkt = {
|
||||
typeName: "google.protobuf.Any";
|
||||
typeUrl: DescField;
|
||||
value: DescField;
|
||||
} | {
|
||||
typeName: "google.protobuf.Timestamp";
|
||||
seconds: DescField;
|
||||
nanos: DescField;
|
||||
} | {
|
||||
typeName: "google.protobuf.Duration";
|
||||
seconds: DescField;
|
||||
nanos: DescField;
|
||||
} | {
|
||||
typeName: "google.protobuf.Struct";
|
||||
fields: DescField & {
|
||||
fieldKind: "map";
|
||||
};
|
||||
} | {
|
||||
typeName: "google.protobuf.Value";
|
||||
kind: DescOneof;
|
||||
nullValue: DescField & {
|
||||
fieldKind: "enum";
|
||||
};
|
||||
numberValue: DescField;
|
||||
stringValue: DescField;
|
||||
boolValue: DescField;
|
||||
structValue: DescField & {
|
||||
fieldKind: "message";
|
||||
};
|
||||
listValue: DescField & {
|
||||
fieldKind: "message";
|
||||
};
|
||||
} | {
|
||||
typeName: "google.protobuf.ListValue";
|
||||
values: DescField & {
|
||||
fieldKind: "message";
|
||||
};
|
||||
} | {
|
||||
typeName: "google.protobuf.FieldMask";
|
||||
paths: DescField;
|
||||
} | {
|
||||
typeName: "google.protobuf.DoubleValue";
|
||||
value: DescField & {
|
||||
fieldKind: "scalar";
|
||||
};
|
||||
} | {
|
||||
typeName: "google.protobuf.FloatValue";
|
||||
value: DescField & {
|
||||
fieldKind: "scalar";
|
||||
};
|
||||
} | {
|
||||
typeName: "google.protobuf.Int64Value";
|
||||
value: DescField & {
|
||||
fieldKind: "scalar";
|
||||
};
|
||||
} | {
|
||||
typeName: "google.protobuf.UInt64Value";
|
||||
value: DescField & {
|
||||
fieldKind: "scalar";
|
||||
};
|
||||
} | {
|
||||
typeName: "google.protobuf.Int32Value";
|
||||
value: DescField & {
|
||||
fieldKind: "scalar";
|
||||
};
|
||||
} | {
|
||||
typeName: "google.protobuf.UInt32Value";
|
||||
value: DescField & {
|
||||
fieldKind: "scalar";
|
||||
};
|
||||
} | {
|
||||
typeName: "google.protobuf.BoolValue";
|
||||
value: DescField & {
|
||||
fieldKind: "scalar";
|
||||
};
|
||||
} | {
|
||||
typeName: "google.protobuf.StringValue";
|
||||
value: DescField & {
|
||||
fieldKind: "scalar";
|
||||
};
|
||||
} | {
|
||||
typeName: "google.protobuf.BytesValue";
|
||||
value: DescField & {
|
||||
fieldKind: "scalar";
|
||||
};
|
||||
};
|
||||
/**
|
||||
* @deprecated please use reifyWkt from @bufbuild/protoplugin/ecmascript instead
|
||||
*
|
||||
* Reifies a given DescMessage into a more concrete object representing its
|
||||
* respective well-known type. The returned object will contain properties
|
||||
* representing the WKT's defined fields.
|
||||
*
|
||||
* Useful during code generation when immediate access to a particular field
|
||||
* is needed without having to search the object's typename and DescField list.
|
||||
*
|
||||
* Returns undefined if the WKT cannot be completely constructed via the
|
||||
* DescMessage.
|
||||
*/
|
||||
export declare function reifyWkt(message: DescMessage): DescWkt | undefined;
|
||||
export {};
|
||||
+172
@@ -0,0 +1,172 @@
|
||||
"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.reifyWkt = void 0;
|
||||
const scalar_js_1 = require("../scalar.js");
|
||||
/**
|
||||
* @deprecated please use reifyWkt from @bufbuild/protoplugin/ecmascript instead
|
||||
*
|
||||
* Reifies a given DescMessage into a more concrete object representing its
|
||||
* respective well-known type. The returned object will contain properties
|
||||
* representing the WKT's defined fields.
|
||||
*
|
||||
* Useful during code generation when immediate access to a particular field
|
||||
* is needed without having to search the object's typename and DescField list.
|
||||
*
|
||||
* Returns undefined if the WKT cannot be completely constructed via the
|
||||
* DescMessage.
|
||||
*/
|
||||
function reifyWkt(message) {
|
||||
switch (message.typeName) {
|
||||
case "google.protobuf.Any": {
|
||||
const typeUrl = message.fields.find((f) => f.number == 1 &&
|
||||
f.fieldKind == "scalar" &&
|
||||
f.scalar === scalar_js_1.ScalarType.STRING);
|
||||
const value = message.fields.find((f) => f.number == 2 &&
|
||||
f.fieldKind == "scalar" &&
|
||||
f.scalar === scalar_js_1.ScalarType.BYTES);
|
||||
if (typeUrl && value) {
|
||||
return {
|
||||
typeName: message.typeName,
|
||||
typeUrl,
|
||||
value,
|
||||
};
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "google.protobuf.Timestamp": {
|
||||
const seconds = message.fields.find((f) => f.number == 1 &&
|
||||
f.fieldKind == "scalar" &&
|
||||
f.scalar === scalar_js_1.ScalarType.INT64);
|
||||
const nanos = message.fields.find((f) => f.number == 2 &&
|
||||
f.fieldKind == "scalar" &&
|
||||
f.scalar === scalar_js_1.ScalarType.INT32);
|
||||
if (seconds && nanos) {
|
||||
return {
|
||||
typeName: message.typeName,
|
||||
seconds,
|
||||
nanos,
|
||||
};
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "google.protobuf.Duration": {
|
||||
const seconds = message.fields.find((f) => f.number == 1 &&
|
||||
f.fieldKind == "scalar" &&
|
||||
f.scalar === scalar_js_1.ScalarType.INT64);
|
||||
const nanos = message.fields.find((f) => f.number == 2 &&
|
||||
f.fieldKind == "scalar" &&
|
||||
f.scalar === scalar_js_1.ScalarType.INT32);
|
||||
if (seconds && nanos) {
|
||||
return {
|
||||
typeName: message.typeName,
|
||||
seconds,
|
||||
nanos,
|
||||
};
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "google.protobuf.Struct": {
|
||||
const fields = message.fields.find((f) => f.number == 1 && !f.repeated);
|
||||
if ((fields === null || fields === void 0 ? void 0 : fields.fieldKind) !== "map" ||
|
||||
fields.mapValue.kind !== "message" ||
|
||||
fields.mapValue.message.typeName !== "google.protobuf.Value") {
|
||||
break;
|
||||
}
|
||||
return { typeName: message.typeName, fields };
|
||||
}
|
||||
case "google.protobuf.Value": {
|
||||
const kind = message.oneofs.find((o) => o.name === "kind");
|
||||
const nullValue = message.fields.find((f) => f.number == 1 && f.oneof === kind);
|
||||
if ((nullValue === null || nullValue === void 0 ? void 0 : nullValue.fieldKind) !== "enum" ||
|
||||
nullValue.enum.typeName !== "google.protobuf.NullValue") {
|
||||
return undefined;
|
||||
}
|
||||
const numberValue = message.fields.find((f) => f.number == 2 &&
|
||||
f.fieldKind == "scalar" &&
|
||||
f.scalar === scalar_js_1.ScalarType.DOUBLE &&
|
||||
f.oneof === kind);
|
||||
const stringValue = message.fields.find((f) => f.number == 3 &&
|
||||
f.fieldKind == "scalar" &&
|
||||
f.scalar === scalar_js_1.ScalarType.STRING &&
|
||||
f.oneof === kind);
|
||||
const boolValue = message.fields.find((f) => f.number == 4 &&
|
||||
f.fieldKind == "scalar" &&
|
||||
f.scalar === scalar_js_1.ScalarType.BOOL &&
|
||||
f.oneof === kind);
|
||||
const structValue = message.fields.find((f) => f.number == 5 && f.oneof === kind);
|
||||
if ((structValue === null || structValue === void 0 ? void 0 : structValue.fieldKind) !== "message" ||
|
||||
structValue.message.typeName !== "google.protobuf.Struct") {
|
||||
return undefined;
|
||||
}
|
||||
const listValue = message.fields.find((f) => f.number == 6 && f.oneof === kind);
|
||||
if ((listValue === null || listValue === void 0 ? void 0 : listValue.fieldKind) !== "message" ||
|
||||
listValue.message.typeName !== "google.protobuf.ListValue") {
|
||||
return undefined;
|
||||
}
|
||||
if (kind && numberValue && stringValue && boolValue) {
|
||||
return {
|
||||
typeName: message.typeName,
|
||||
kind,
|
||||
nullValue,
|
||||
numberValue,
|
||||
stringValue,
|
||||
boolValue,
|
||||
structValue,
|
||||
listValue,
|
||||
};
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "google.protobuf.ListValue": {
|
||||
const values = message.fields.find((f) => f.number == 1 && f.repeated);
|
||||
if ((values === null || values === void 0 ? void 0 : values.fieldKind) != "message" ||
|
||||
values.message.typeName !== "google.protobuf.Value") {
|
||||
break;
|
||||
}
|
||||
return { typeName: message.typeName, values };
|
||||
}
|
||||
case "google.protobuf.FieldMask": {
|
||||
const paths = message.fields.find((f) => f.number == 1 &&
|
||||
f.fieldKind == "scalar" &&
|
||||
f.scalar === scalar_js_1.ScalarType.STRING &&
|
||||
f.repeated);
|
||||
if (paths) {
|
||||
return { typeName: message.typeName, paths };
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "google.protobuf.DoubleValue":
|
||||
case "google.protobuf.FloatValue":
|
||||
case "google.protobuf.Int64Value":
|
||||
case "google.protobuf.UInt64Value":
|
||||
case "google.protobuf.Int32Value":
|
||||
case "google.protobuf.UInt32Value":
|
||||
case "google.protobuf.BoolValue":
|
||||
case "google.protobuf.StringValue":
|
||||
case "google.protobuf.BytesValue": {
|
||||
const value = message.fields.find((f) => f.number == 1 && f.name == "value");
|
||||
if (!value) {
|
||||
break;
|
||||
}
|
||||
if (value.fieldKind !== "scalar") {
|
||||
break;
|
||||
}
|
||||
return { typeName: message.typeName, value };
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
exports.reifyWkt = reifyWkt;
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
import { LongType, ScalarType } from "../scalar.js";
|
||||
import type { ScalarValue } from "../scalar.js";
|
||||
/**
|
||||
* Returns true if both scalar values are equal.
|
||||
*/
|
||||
export declare function scalarEquals(type: ScalarType, a: string | boolean | number | bigint | Uint8Array | undefined, b: string | boolean | number | bigint | Uint8Array | undefined): boolean;
|
||||
/**
|
||||
* Returns the zero value for the given scalar type.
|
||||
*/
|
||||
export declare function scalarZeroValue<T extends ScalarType, L extends LongType>(type: T, longType: L): ScalarValue<T, L>;
|
||||
/**
|
||||
* Returns true for a zero-value. For example, an integer has the zero-value `0`,
|
||||
* a boolean is `false`, a string is `""`, and bytes is an empty Uint8Array.
|
||||
*
|
||||
* In proto3, zero-values are not written to the wire, unless the field is
|
||||
* optional or repeated.
|
||||
*/
|
||||
export declare function isScalarZeroValue(type: ScalarType, value: unknown): boolean;
|
||||
+105
@@ -0,0 +1,105 @@
|
||||
"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.isScalarZeroValue = exports.scalarZeroValue = exports.scalarEquals = void 0;
|
||||
const proto_int64_js_1 = require("../proto-int64.js");
|
||||
const scalar_js_1 = require("../scalar.js");
|
||||
/**
|
||||
* Returns true if both scalar values are equal.
|
||||
*/
|
||||
function scalarEquals(type, a, b) {
|
||||
if (a === b) {
|
||||
// This correctly matches equal values except BYTES and (possibly) 64-bit integers.
|
||||
return true;
|
||||
}
|
||||
// Special case BYTES - we need to compare each byte individually
|
||||
if (type == scalar_js_1.ScalarType.BYTES) {
|
||||
if (!(a instanceof Uint8Array) || !(b instanceof Uint8Array)) {
|
||||
return false;
|
||||
}
|
||||
if (a.length !== b.length) {
|
||||
return false;
|
||||
}
|
||||
for (let i = 0; i < a.length; i++) {
|
||||
if (a[i] !== b[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
// Special case 64-bit integers - we support number, string and bigint representation.
|
||||
// eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check
|
||||
switch (type) {
|
||||
case scalar_js_1.ScalarType.UINT64:
|
||||
case scalar_js_1.ScalarType.FIXED64:
|
||||
case scalar_js_1.ScalarType.INT64:
|
||||
case scalar_js_1.ScalarType.SFIXED64:
|
||||
case scalar_js_1.ScalarType.SINT64:
|
||||
// Loose comparison will match between 0n, 0 and "0".
|
||||
return a == b;
|
||||
}
|
||||
// Anything that hasn't been caught by strict comparison or special cased
|
||||
// BYTES and 64-bit integers is not equal.
|
||||
return false;
|
||||
}
|
||||
exports.scalarEquals = scalarEquals;
|
||||
/**
|
||||
* Returns the zero value for the given scalar type.
|
||||
*/
|
||||
function scalarZeroValue(type, longType) {
|
||||
switch (type) {
|
||||
case scalar_js_1.ScalarType.BOOL:
|
||||
return false;
|
||||
case scalar_js_1.ScalarType.UINT64:
|
||||
case scalar_js_1.ScalarType.FIXED64:
|
||||
case scalar_js_1.ScalarType.INT64:
|
||||
case scalar_js_1.ScalarType.SFIXED64:
|
||||
case scalar_js_1.ScalarType.SINT64:
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-enum-comparison -- acceptable since it's covered by tests
|
||||
return (longType == 0 ? proto_int64_js_1.protoInt64.zero : "0");
|
||||
case scalar_js_1.ScalarType.DOUBLE:
|
||||
case scalar_js_1.ScalarType.FLOAT:
|
||||
return 0.0;
|
||||
case scalar_js_1.ScalarType.BYTES:
|
||||
return new Uint8Array(0);
|
||||
case scalar_js_1.ScalarType.STRING:
|
||||
return "";
|
||||
default:
|
||||
// Handles INT32, UINT32, SINT32, FIXED32, SFIXED32.
|
||||
// We do not use individual cases to save a few bytes code size.
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
exports.scalarZeroValue = scalarZeroValue;
|
||||
/**
|
||||
* Returns true for a zero-value. For example, an integer has the zero-value `0`,
|
||||
* a boolean is `false`, a string is `""`, and bytes is an empty Uint8Array.
|
||||
*
|
||||
* In proto3, zero-values are not written to the wire, unless the field is
|
||||
* optional or repeated.
|
||||
*/
|
||||
function isScalarZeroValue(type, value) {
|
||||
switch (type) {
|
||||
case scalar_js_1.ScalarType.BOOL:
|
||||
return value === false;
|
||||
case scalar_js_1.ScalarType.STRING:
|
||||
return value === "";
|
||||
case scalar_js_1.ScalarType.BYTES:
|
||||
return value instanceof Uint8Array && !value.byteLength;
|
||||
default:
|
||||
return value == 0; // Loose comparison matches 0n, 0 and "0"
|
||||
}
|
||||
}
|
||||
exports.isScalarZeroValue = isScalarZeroValue;
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
import type { DescEnum } from "../descriptor-set.js";
|
||||
import { ScalarType } from "../scalar.js";
|
||||
export declare function parseTextFormatEnumValue(descEnum: DescEnum, value: string): number;
|
||||
export declare function parseTextFormatScalarValue(type: ScalarType, value: string): number | boolean | string | bigint | Uint8Array;
|
||||
+189
@@ -0,0 +1,189 @@
|
||||
"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.parseTextFormatScalarValue = exports.parseTextFormatEnumValue = void 0;
|
||||
const assert_js_1 = require("./assert.js");
|
||||
const proto_int64_js_1 = require("../proto-int64.js");
|
||||
const scalar_js_1 = require("../scalar.js");
|
||||
function parseTextFormatEnumValue(descEnum, value) {
|
||||
const enumValue = descEnum.values.find((v) => v.name === value);
|
||||
(0, assert_js_1.assert)(enumValue, `cannot parse ${descEnum.name} default value: ${value}`);
|
||||
return enumValue.number;
|
||||
}
|
||||
exports.parseTextFormatEnumValue = parseTextFormatEnumValue;
|
||||
function parseTextFormatScalarValue(type, value) {
|
||||
switch (type) {
|
||||
case scalar_js_1.ScalarType.STRING:
|
||||
return value;
|
||||
case scalar_js_1.ScalarType.BYTES: {
|
||||
const u = unescapeBytesDefaultValue(value);
|
||||
if (u === false) {
|
||||
throw new Error(`cannot parse ${scalar_js_1.ScalarType[type]} default value: ${value}`);
|
||||
}
|
||||
return u;
|
||||
}
|
||||
case scalar_js_1.ScalarType.INT64:
|
||||
case scalar_js_1.ScalarType.SFIXED64:
|
||||
case scalar_js_1.ScalarType.SINT64:
|
||||
return proto_int64_js_1.protoInt64.parse(value);
|
||||
case scalar_js_1.ScalarType.UINT64:
|
||||
case scalar_js_1.ScalarType.FIXED64:
|
||||
return proto_int64_js_1.protoInt64.uParse(value);
|
||||
case scalar_js_1.ScalarType.DOUBLE:
|
||||
case scalar_js_1.ScalarType.FLOAT:
|
||||
switch (value) {
|
||||
case "inf":
|
||||
return Number.POSITIVE_INFINITY;
|
||||
case "-inf":
|
||||
return Number.NEGATIVE_INFINITY;
|
||||
case "nan":
|
||||
return Number.NaN;
|
||||
default:
|
||||
return parseFloat(value);
|
||||
}
|
||||
case scalar_js_1.ScalarType.BOOL:
|
||||
return value === "true";
|
||||
case scalar_js_1.ScalarType.INT32:
|
||||
case scalar_js_1.ScalarType.UINT32:
|
||||
case scalar_js_1.ScalarType.SINT32:
|
||||
case scalar_js_1.ScalarType.FIXED32:
|
||||
case scalar_js_1.ScalarType.SFIXED32:
|
||||
return parseInt(value, 10);
|
||||
}
|
||||
}
|
||||
exports.parseTextFormatScalarValue = parseTextFormatScalarValue;
|
||||
/**
|
||||
* Parses a text-encoded default value (proto2) of a BYTES field.
|
||||
*/
|
||||
function unescapeBytesDefaultValue(str) {
|
||||
const b = [];
|
||||
const input = {
|
||||
tail: str,
|
||||
c: "",
|
||||
next() {
|
||||
if (this.tail.length == 0) {
|
||||
return false;
|
||||
}
|
||||
this.c = this.tail[0];
|
||||
this.tail = this.tail.substring(1);
|
||||
return true;
|
||||
},
|
||||
take(n) {
|
||||
if (this.tail.length >= n) {
|
||||
const r = this.tail.substring(0, n);
|
||||
this.tail = this.tail.substring(n);
|
||||
return r;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
};
|
||||
while (input.next()) {
|
||||
switch (input.c) {
|
||||
case "\\":
|
||||
if (input.next()) {
|
||||
switch (input.c) {
|
||||
case "\\":
|
||||
b.push(input.c.charCodeAt(0));
|
||||
break;
|
||||
case "b":
|
||||
b.push(0x08);
|
||||
break;
|
||||
case "f":
|
||||
b.push(0x0c);
|
||||
break;
|
||||
case "n":
|
||||
b.push(0x0a);
|
||||
break;
|
||||
case "r":
|
||||
b.push(0x0d);
|
||||
break;
|
||||
case "t":
|
||||
b.push(0x09);
|
||||
break;
|
||||
case "v":
|
||||
b.push(0x0b);
|
||||
break;
|
||||
case "0":
|
||||
case "1":
|
||||
case "2":
|
||||
case "3":
|
||||
case "4":
|
||||
case "5":
|
||||
case "6":
|
||||
case "7": {
|
||||
const s = input.c;
|
||||
const t = input.take(2);
|
||||
if (t === false) {
|
||||
return false;
|
||||
}
|
||||
const n = parseInt(s + t, 8);
|
||||
if (isNaN(n)) {
|
||||
return false;
|
||||
}
|
||||
b.push(n);
|
||||
break;
|
||||
}
|
||||
case "x": {
|
||||
const s = input.c;
|
||||
const t = input.take(2);
|
||||
if (t === false) {
|
||||
return false;
|
||||
}
|
||||
const n = parseInt(s + t, 16);
|
||||
if (isNaN(n)) {
|
||||
return false;
|
||||
}
|
||||
b.push(n);
|
||||
break;
|
||||
}
|
||||
case "u": {
|
||||
const s = input.c;
|
||||
const t = input.take(4);
|
||||
if (t === false) {
|
||||
return false;
|
||||
}
|
||||
const n = parseInt(s + t, 16);
|
||||
if (isNaN(n)) {
|
||||
return false;
|
||||
}
|
||||
const chunk = new Uint8Array(4);
|
||||
const view = new DataView(chunk.buffer);
|
||||
view.setInt32(0, n, true);
|
||||
b.push(chunk[0], chunk[1], chunk[2], chunk[3]);
|
||||
break;
|
||||
}
|
||||
case "U": {
|
||||
const s = input.c;
|
||||
const t = input.take(8);
|
||||
if (t === false) {
|
||||
return false;
|
||||
}
|
||||
const tc = proto_int64_js_1.protoInt64.uEnc(s + t);
|
||||
const chunk = new Uint8Array(8);
|
||||
const view = new DataView(chunk.buffer);
|
||||
view.setInt32(0, tc.lo, true);
|
||||
view.setInt32(4, tc.hi, true);
|
||||
b.push(chunk[0], chunk[1], chunk[2], chunk[3], chunk[4], chunk[5], chunk[6], chunk[7]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
b.push(input.c.charCodeAt(0));
|
||||
}
|
||||
}
|
||||
return new Uint8Array(b);
|
||||
}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
import type { Util } from "./util.js";
|
||||
export declare function makeUtilCommon(): Omit<Util, "newFieldList" | "initFields">;
|
||||
+247
@@ -0,0 +1,247 @@
|
||||
"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.makeUtilCommon = void 0;
|
||||
const enum_js_1 = require("./enum.js");
|
||||
const scalars_js_1 = require("./scalars.js");
|
||||
const scalar_js_1 = require("../scalar.js");
|
||||
const is_message_js_1 = require("../is-message.js");
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any,@typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-return,@typescript-eslint/no-unsafe-argument,no-case-declarations */
|
||||
function makeUtilCommon() {
|
||||
return {
|
||||
setEnumType: enum_js_1.setEnumType,
|
||||
initPartial(source, target) {
|
||||
if (source === undefined) {
|
||||
return;
|
||||
}
|
||||
const type = target.getType();
|
||||
for (const member of type.fields.byMember()) {
|
||||
const localName = member.localName, t = target, s = source;
|
||||
if (s[localName] == null) {
|
||||
// TODO if source is a Message instance, we should use isFieldSet() here to support future field presence
|
||||
continue;
|
||||
}
|
||||
switch (member.kind) {
|
||||
case "oneof":
|
||||
const sk = s[localName].case;
|
||||
if (sk === undefined) {
|
||||
continue;
|
||||
}
|
||||
const sourceField = member.findField(sk);
|
||||
let val = s[localName].value;
|
||||
if (sourceField &&
|
||||
sourceField.kind == "message" &&
|
||||
!(0, is_message_js_1.isMessage)(val, sourceField.T)) {
|
||||
val = new sourceField.T(val);
|
||||
}
|
||||
else if (sourceField &&
|
||||
sourceField.kind === "scalar" &&
|
||||
sourceField.T === scalar_js_1.ScalarType.BYTES) {
|
||||
val = toU8Arr(val);
|
||||
}
|
||||
t[localName] = { case: sk, value: val };
|
||||
break;
|
||||
case "scalar":
|
||||
case "enum":
|
||||
let copy = s[localName];
|
||||
if (member.T === scalar_js_1.ScalarType.BYTES) {
|
||||
copy = member.repeated
|
||||
? copy.map(toU8Arr)
|
||||
: toU8Arr(copy);
|
||||
}
|
||||
t[localName] = copy;
|
||||
break;
|
||||
case "map":
|
||||
switch (member.V.kind) {
|
||||
case "scalar":
|
||||
case "enum":
|
||||
if (member.V.T === scalar_js_1.ScalarType.BYTES) {
|
||||
for (const [k, v] of Object.entries(s[localName])) {
|
||||
t[localName][k] = toU8Arr(v);
|
||||
}
|
||||
}
|
||||
else {
|
||||
Object.assign(t[localName], s[localName]);
|
||||
}
|
||||
break;
|
||||
case "message":
|
||||
const messageType = member.V.T;
|
||||
for (const k of Object.keys(s[localName])) {
|
||||
let val = s[localName][k];
|
||||
if (!messageType.fieldWrapper) {
|
||||
// We only take partial input for messages that are not a wrapper type.
|
||||
// For those messages, we recursively normalize the partial input.
|
||||
val = new messageType(val);
|
||||
}
|
||||
t[localName][k] = val;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case "message":
|
||||
const mt = member.T;
|
||||
if (member.repeated) {
|
||||
t[localName] = s[localName].map((val) => (0, is_message_js_1.isMessage)(val, mt) ? val : new mt(val));
|
||||
}
|
||||
else {
|
||||
const val = s[localName];
|
||||
if (mt.fieldWrapper) {
|
||||
if (
|
||||
// We can't use BytesValue.typeName as that will create a circular import
|
||||
mt.typeName === "google.protobuf.BytesValue") {
|
||||
t[localName] = toU8Arr(val);
|
||||
}
|
||||
else {
|
||||
t[localName] = val;
|
||||
}
|
||||
}
|
||||
else {
|
||||
t[localName] = (0, is_message_js_1.isMessage)(val, mt) ? val : new mt(val);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
// TODO use isFieldSet() here to support future field presence
|
||||
equals(type, a, b) {
|
||||
if (a === b) {
|
||||
return true;
|
||||
}
|
||||
if (!a || !b) {
|
||||
return false;
|
||||
}
|
||||
return type.fields.byMember().every((m) => {
|
||||
const va = a[m.localName];
|
||||
const vb = b[m.localName];
|
||||
if (m.repeated) {
|
||||
if (va.length !== vb.length) {
|
||||
return false;
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check -- repeated fields are never "map"
|
||||
switch (m.kind) {
|
||||
case "message":
|
||||
return va.every((a, i) => m.T.equals(a, vb[i]));
|
||||
case "scalar":
|
||||
return va.every((a, i) => (0, scalars_js_1.scalarEquals)(m.T, a, vb[i]));
|
||||
case "enum":
|
||||
return va.every((a, i) => (0, scalars_js_1.scalarEquals)(scalar_js_1.ScalarType.INT32, a, vb[i]));
|
||||
}
|
||||
throw new Error(`repeated cannot contain ${m.kind}`);
|
||||
}
|
||||
switch (m.kind) {
|
||||
case "message":
|
||||
let a = va;
|
||||
let b = vb;
|
||||
if (m.T.fieldWrapper) {
|
||||
if (a !== undefined && !(0, is_message_js_1.isMessage)(a)) {
|
||||
a = m.T.fieldWrapper.wrapField(a);
|
||||
}
|
||||
if (b !== undefined && !(0, is_message_js_1.isMessage)(b)) {
|
||||
b = m.T.fieldWrapper.wrapField(b);
|
||||
}
|
||||
}
|
||||
return m.T.equals(a, b);
|
||||
case "enum":
|
||||
return (0, scalars_js_1.scalarEquals)(scalar_js_1.ScalarType.INT32, va, vb);
|
||||
case "scalar":
|
||||
return (0, scalars_js_1.scalarEquals)(m.T, va, vb);
|
||||
case "oneof":
|
||||
if (va.case !== vb.case) {
|
||||
return false;
|
||||
}
|
||||
const s = m.findField(va.case);
|
||||
if (s === undefined) {
|
||||
return true;
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check -- oneof fields are never "map"
|
||||
switch (s.kind) {
|
||||
case "message":
|
||||
return s.T.equals(va.value, vb.value);
|
||||
case "enum":
|
||||
return (0, scalars_js_1.scalarEquals)(scalar_js_1.ScalarType.INT32, va.value, vb.value);
|
||||
case "scalar":
|
||||
return (0, scalars_js_1.scalarEquals)(s.T, va.value, vb.value);
|
||||
}
|
||||
throw new Error(`oneof cannot contain ${s.kind}`);
|
||||
case "map":
|
||||
const keys = Object.keys(va).concat(Object.keys(vb));
|
||||
switch (m.V.kind) {
|
||||
case "message":
|
||||
const messageType = m.V.T;
|
||||
return keys.every((k) => messageType.equals(va[k], vb[k]));
|
||||
case "enum":
|
||||
return keys.every((k) => (0, scalars_js_1.scalarEquals)(scalar_js_1.ScalarType.INT32, va[k], vb[k]));
|
||||
case "scalar":
|
||||
const scalarType = m.V.T;
|
||||
return keys.every((k) => (0, scalars_js_1.scalarEquals)(scalarType, va[k], vb[k]));
|
||||
}
|
||||
break;
|
||||
}
|
||||
});
|
||||
},
|
||||
// TODO use isFieldSet() here to support future field presence
|
||||
clone(message) {
|
||||
const type = message.getType(), target = new type(), any = target;
|
||||
for (const member of type.fields.byMember()) {
|
||||
const source = message[member.localName];
|
||||
let copy;
|
||||
if (member.repeated) {
|
||||
copy = source.map(cloneSingularField);
|
||||
}
|
||||
else if (member.kind == "map") {
|
||||
copy = any[member.localName];
|
||||
for (const [key, v] of Object.entries(source)) {
|
||||
copy[key] = cloneSingularField(v);
|
||||
}
|
||||
}
|
||||
else if (member.kind == "oneof") {
|
||||
const f = member.findField(source.case);
|
||||
copy = f
|
||||
? { case: source.case, value: cloneSingularField(source.value) }
|
||||
: { case: undefined };
|
||||
}
|
||||
else {
|
||||
copy = cloneSingularField(source);
|
||||
}
|
||||
any[member.localName] = copy;
|
||||
}
|
||||
for (const uf of type.runtime.bin.listUnknownFields(message)) {
|
||||
type.runtime.bin.onUnknownField(any, uf.no, uf.wireType, uf.data);
|
||||
}
|
||||
return target;
|
||||
},
|
||||
};
|
||||
}
|
||||
exports.makeUtilCommon = makeUtilCommon;
|
||||
// clone a single field value - i.e. the element type of repeated fields, the value type of maps
|
||||
function cloneSingularField(value) {
|
||||
if (value === undefined) {
|
||||
return value;
|
||||
}
|
||||
if ((0, is_message_js_1.isMessage)(value)) {
|
||||
return value.clone();
|
||||
}
|
||||
if (value instanceof Uint8Array) {
|
||||
const c = new Uint8Array(value.byteLength);
|
||||
c.set(value);
|
||||
return c;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
// converts any ArrayLike<number> to Uint8Array if necessary.
|
||||
function toU8Arr(input) {
|
||||
return input instanceof Uint8Array ? input : new Uint8Array(input);
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
import type { FieldListSource } from "./field-list.js";
|
||||
import type { FieldList } from "../field-list.js";
|
||||
import type { EnumObject } from "./enum.js";
|
||||
import type { Message, PartialMessage, PlainMessage } from "../message.js";
|
||||
import type { MessageType } from "../message-type.js";
|
||||
import type { EnumValueInfo } from "../enum.js";
|
||||
/**
|
||||
* Provides utilities used by generated code.
|
||||
* All methods are internal and are not safe to use, they may break with a
|
||||
* future release.
|
||||
*/
|
||||
export interface Util {
|
||||
/**
|
||||
* Create a field list
|
||||
*/
|
||||
newFieldList(fields: FieldListSource): FieldList;
|
||||
/**
|
||||
* Sets reflection information on a generated enum.
|
||||
*/
|
||||
setEnumType(enumObject: EnumObject, typeName: string, values: Omit<EnumValueInfo, "localName">[], opt?: {}): void;
|
||||
/**
|
||||
* Set default field values on the target message.
|
||||
*/
|
||||
initFields(target: Message): void;
|
||||
/**
|
||||
* Set specified field values on the target message, recursively.
|
||||
*/
|
||||
initPartial<T extends Message<T>>(source: PartialMessage<T> | undefined, target: T): void;
|
||||
/**
|
||||
* Compares two messages of the same type recursively.
|
||||
* Will also return true if both messages are `undefined` or `null`.
|
||||
*/
|
||||
equals<T extends Message<T>>(type: MessageType<T>, a: T | PlainMessage<T> | undefined | null, b: T | PlainMessage<T> | undefined | null): boolean;
|
||||
/**
|
||||
* Create a deep copy.
|
||||
*/
|
||||
clone<T extends Message<T>>(message: T): T;
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
"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 });
|
||||
Reference in New Issue
Block a user