You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

140 lines
4.7 KiB

// 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.
import { isScalarZeroValue, scalarZeroValue } from "./scalar.js";
// bootstrap-inject google.protobuf.FeatureSet.FieldPresence.IMPLICIT: const $name: FeatureSet_FieldPresence.$localName = $number;
const IMPLICIT = 2;
export const unsafeLocal = Symbol.for("reflect unsafe local");
/**
* Return the selected field of a oneof group.
*
* @private
*/
export function unsafeOneofCase(target, // eslint-disable-line @typescript-eslint/no-explicit-any -- `any` is the best choice for dynamic access
oneof) {
const c = target[oneof.localName].case;
if (c === undefined) {
return c;
}
return oneof.fields.find((f) => f.localName === c);
}
/**
* Returns true if the field is set.
*
* @private
*/
export function unsafeIsSet(target, // eslint-disable-line @typescript-eslint/no-explicit-any -- `any` is the best choice for dynamic access
field) {
const name = field.localName;
if (field.oneof) {
return target[field.oneof.localName].case === name; // eslint-disable-line @typescript-eslint/no-unsafe-member-access
}
if (field.presence != IMPLICIT) {
// Fields with explicit presence have properties on the prototype chain
// for default / zero values (except for proto3).
return (target[name] !== undefined &&
Object.prototype.hasOwnProperty.call(target, name));
}
// eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check
switch (field.fieldKind) {
case "list":
return target[name].length > 0;
case "map":
return Object.keys(target[name]).length > 0; // eslint-disable-line @typescript-eslint/no-unsafe-argument
case "scalar":
return !isScalarZeroValue(field.scalar, target[name]);
case "enum":
return target[name] !== field.enum.values[0].number;
}
throw new Error("message field with implicit presence");
}
/**
* Returns true if the field is set, but only for singular fields with explicit
* presence (proto2).
*
* @private
*/
export function unsafeIsSetExplicit(target, localName) {
return (Object.prototype.hasOwnProperty.call(target, localName) &&
target[localName] !== undefined);
}
/**
* Return a field value, respecting oneof groups.
*
* @private
*/
export function unsafeGet(target, field) {
if (field.oneof) {
const oneof = target[field.oneof.localName];
if (oneof.case === field.localName) {
return oneof.value;
}
return undefined;
}
return target[field.localName];
}
/**
* Set a field value, respecting oneof groups.
*
* @private
*/
export function unsafeSet(target, field, value) {
if (field.oneof) {
target[field.oneof.localName] = {
case: field.localName,
value: value,
};
}
else {
target[field.localName] = value;
}
}
/**
* Resets the field, so that unsafeIsSet() will return false.
*
* @private
*/
export function unsafeClear(target, // eslint-disable-line @typescript-eslint/no-explicit-any -- `any` is the best choice for dynamic access
field) {
const name = field.localName;
if (field.oneof) {
const oneofLocalName = field.oneof.localName;
if (target[oneofLocalName].case === name) {
target[oneofLocalName] = { case: undefined };
}
}
else if (field.presence != IMPLICIT) {
// Fields with explicit presence have properties on the prototype chain
// for default / zero values (except for proto3). By deleting their own
// property, the field is reset.
delete target[name];
}
else {
// eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check
switch (field.fieldKind) {
case "map":
target[name] = {};
break;
case "list":
target[name] = [];
break;
case "enum":
target[name] = field.enum.values[0].number;
break;
case "scalar":
target[name] = scalarZeroValue(field.scalar, field.longAsString);
break;
}
}
}