// 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 { scalarZeroValue } from "./scalars.js"; import { WireType } from "../binary-encoding.js"; /** * Create a new extension using the given runtime. */ export 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, }; } /** * Create a container that allows us to read extension fields into it with the * same logic as regular fields. */ export function createExtensionContainer(extension) { const localName = extension.field.localName; const container = Object.create(null); container[localName] = initExtensionField(extension); return [container, () => container[localName]]; } 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 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. */ export 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); }