Erster Commit
This commit is contained in:
+264
@@ -0,0 +1,264 @@
|
||||
"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.createRegistryFromDescriptors = void 0;
|
||||
const assert_js_1 = require("./private/assert.js");
|
||||
const proto3_js_1 = require("./proto3.js");
|
||||
const proto2_js_1 = require("./proto2.js");
|
||||
const names_js_1 = require("./private/names.js");
|
||||
const timestamp_pb_js_1 = require("./google/protobuf/timestamp_pb.js");
|
||||
const duration_pb_js_1 = require("./google/protobuf/duration_pb.js");
|
||||
const any_pb_js_1 = require("./google/protobuf/any_pb.js");
|
||||
const empty_pb_js_1 = require("./google/protobuf/empty_pb.js");
|
||||
const field_mask_pb_js_1 = require("./google/protobuf/field_mask_pb.js");
|
||||
const struct_pb_js_1 = require("./google/protobuf/struct_pb.js");
|
||||
const enum_js_1 = require("./private/enum.js");
|
||||
const wrappers_pb_js_1 = require("./google/protobuf/wrappers_pb.js");
|
||||
const descriptor_pb_js_1 = require("./google/protobuf/descriptor_pb.js");
|
||||
const create_descriptor_set_js_1 = require("./create-descriptor-set.js");
|
||||
const is_message_js_1 = require("./is-message.js");
|
||||
// well-known message types with specialized JSON representation
|
||||
const wkMessages = [
|
||||
any_pb_js_1.Any,
|
||||
duration_pb_js_1.Duration,
|
||||
empty_pb_js_1.Empty,
|
||||
field_mask_pb_js_1.FieldMask,
|
||||
struct_pb_js_1.Struct,
|
||||
struct_pb_js_1.Value,
|
||||
struct_pb_js_1.ListValue,
|
||||
timestamp_pb_js_1.Timestamp,
|
||||
duration_pb_js_1.Duration,
|
||||
wrappers_pb_js_1.DoubleValue,
|
||||
wrappers_pb_js_1.FloatValue,
|
||||
wrappers_pb_js_1.Int64Value,
|
||||
wrappers_pb_js_1.Int32Value,
|
||||
wrappers_pb_js_1.UInt32Value,
|
||||
wrappers_pb_js_1.UInt64Value,
|
||||
wrappers_pb_js_1.BoolValue,
|
||||
wrappers_pb_js_1.StringValue,
|
||||
wrappers_pb_js_1.BytesValue,
|
||||
];
|
||||
// well-known enum types with specialized JSON representation
|
||||
const wkEnums = [(0, enum_js_1.getEnumType)(struct_pb_js_1.NullValue)];
|
||||
/**
|
||||
* Create a registry from a set of descriptors. The types returned by this
|
||||
* registry behave exactly like types from generated code.
|
||||
*
|
||||
* This function accepts google.protobuf.FileDescriptorSet in serialized or
|
||||
* deserialized form. Alternatively, it also accepts a DescriptorSet (see
|
||||
* createDescriptorSet()).
|
||||
*
|
||||
* By default, all well-known types with a specialized JSON representation
|
||||
* are replaced with their generated counterpart in this package.
|
||||
*/
|
||||
function createRegistryFromDescriptors(input, replaceWkt = true) {
|
||||
const set = input instanceof Uint8Array || (0, is_message_js_1.isMessage)(input, descriptor_pb_js_1.FileDescriptorSet)
|
||||
? (0, create_descriptor_set_js_1.createDescriptorSet)(input)
|
||||
: input;
|
||||
const enums = new Map();
|
||||
const messages = new Map();
|
||||
const extensions = new Map();
|
||||
const extensionsByExtendee = new Map();
|
||||
const services = {};
|
||||
if (replaceWkt) {
|
||||
for (const mt of wkMessages) {
|
||||
messages.set(mt.typeName, mt);
|
||||
}
|
||||
for (const et of wkEnums) {
|
||||
enums.set(et.typeName, et);
|
||||
}
|
||||
}
|
||||
return {
|
||||
/**
|
||||
* May raise an error on invalid descriptors.
|
||||
*/
|
||||
findEnum(typeName) {
|
||||
const existing = enums.get(typeName);
|
||||
if (existing) {
|
||||
return existing;
|
||||
}
|
||||
const desc = set.enums.get(typeName);
|
||||
if (!desc) {
|
||||
return undefined;
|
||||
}
|
||||
const runtime = desc.file.syntax == "proto3" ? proto3_js_1.proto3 : proto2_js_1.proto2;
|
||||
const type = runtime.makeEnumType(typeName, desc.values.map((u) => ({
|
||||
no: u.number,
|
||||
name: u.name,
|
||||
localName: (0, names_js_1.localName)(u),
|
||||
})), {});
|
||||
enums.set(typeName, type);
|
||||
return type;
|
||||
},
|
||||
/**
|
||||
* May raise an error on invalid descriptors.
|
||||
*/
|
||||
findMessage(typeName) {
|
||||
const existing = messages.get(typeName);
|
||||
if (existing) {
|
||||
return existing;
|
||||
}
|
||||
const desc = set.messages.get(typeName);
|
||||
if (!desc) {
|
||||
return undefined;
|
||||
}
|
||||
const runtime = desc.file.syntax == "proto3" ? proto3_js_1.proto3 : proto2_js_1.proto2;
|
||||
const fields = [];
|
||||
const type = runtime.makeMessageType(typeName, () => fields, {
|
||||
localName: (0, names_js_1.localName)(desc),
|
||||
});
|
||||
messages.set(typeName, type);
|
||||
for (const field of desc.fields) {
|
||||
fields.push(makeFieldInfo(field, this));
|
||||
}
|
||||
return type;
|
||||
},
|
||||
/**
|
||||
* May raise an error on invalid descriptors.
|
||||
*/
|
||||
findService(typeName) {
|
||||
const existing = services[typeName];
|
||||
if (existing) {
|
||||
return existing;
|
||||
}
|
||||
const desc = set.services.get(typeName);
|
||||
if (!desc) {
|
||||
return undefined;
|
||||
}
|
||||
const methods = {};
|
||||
for (const method of desc.methods) {
|
||||
const I = resolve(method.input, this, method);
|
||||
const O = resolve(method.output, this, method);
|
||||
methods[(0, names_js_1.localName)(method)] = {
|
||||
name: method.name,
|
||||
I,
|
||||
O,
|
||||
kind: method.methodKind,
|
||||
idempotency: method.idempotency,
|
||||
// We do not surface options at this time
|
||||
// options: {},
|
||||
};
|
||||
}
|
||||
return (services[typeName] = {
|
||||
typeName: desc.typeName,
|
||||
methods,
|
||||
});
|
||||
},
|
||||
/**
|
||||
* May raise an error on invalid descriptors.
|
||||
*/
|
||||
findExtensionFor(typeName, no) {
|
||||
var _a;
|
||||
if (!set.messages.has(typeName)) {
|
||||
return undefined;
|
||||
}
|
||||
let extensionsByNo = extensionsByExtendee.get(typeName);
|
||||
if (!extensionsByNo) {
|
||||
// maintain a lookup for extension desc by number
|
||||
extensionsByNo = new Map();
|
||||
extensionsByExtendee.set(typeName, extensionsByNo);
|
||||
for (const desc of set.extensions.values()) {
|
||||
if (desc.extendee.typeName == typeName) {
|
||||
extensionsByNo.set(desc.number, desc);
|
||||
}
|
||||
}
|
||||
}
|
||||
const desc = (_a = extensionsByExtendee.get(typeName)) === null || _a === void 0 ? void 0 : _a.get(no);
|
||||
return desc ? this.findExtension(desc.typeName) : undefined;
|
||||
},
|
||||
/**
|
||||
* May raise an error on invalid descriptors.
|
||||
*/
|
||||
findExtension(typeName) {
|
||||
const existing = extensions.get(typeName);
|
||||
if (existing) {
|
||||
return existing;
|
||||
}
|
||||
const desc = set.extensions.get(typeName);
|
||||
if (!desc) {
|
||||
return undefined;
|
||||
}
|
||||
const extendee = resolve(desc.extendee, this, desc);
|
||||
const runtime = desc.file.syntax == "proto3" ? proto3_js_1.proto3 : proto2_js_1.proto2;
|
||||
const ext = runtime.makeExtension(typeName, extendee, makeFieldInfo(desc, this));
|
||||
extensions.set(typeName, ext);
|
||||
return ext;
|
||||
},
|
||||
};
|
||||
}
|
||||
exports.createRegistryFromDescriptors = createRegistryFromDescriptors;
|
||||
function makeFieldInfo(desc, registry) {
|
||||
var _a;
|
||||
const f = {
|
||||
kind: desc.fieldKind,
|
||||
no: desc.number,
|
||||
name: desc.name,
|
||||
jsonName: desc.jsonName,
|
||||
delimited: desc.proto.type == descriptor_pb_js_1.FieldDescriptorProto_Type.GROUP,
|
||||
repeated: desc.repeated,
|
||||
packed: desc.packed,
|
||||
oneof: (_a = desc.oneof) === null || _a === void 0 ? void 0 : _a.name,
|
||||
opt: desc.optional,
|
||||
req: desc.proto.label === descriptor_pb_js_1.FieldDescriptorProto_Label.REQUIRED,
|
||||
};
|
||||
switch (desc.fieldKind) {
|
||||
case "map": {
|
||||
(0, assert_js_1.assert)(desc.kind == "field"); // maps are not allowed for extensions
|
||||
let T;
|
||||
switch (desc.mapValue.kind) {
|
||||
case "scalar":
|
||||
T = desc.mapValue.scalar;
|
||||
break;
|
||||
case "enum": {
|
||||
T = resolve(desc.mapValue.enum, registry, desc);
|
||||
break;
|
||||
}
|
||||
case "message": {
|
||||
T = resolve(desc.mapValue.message, registry, desc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
f.K = desc.mapKey;
|
||||
f.V = {
|
||||
kind: desc.mapValue.kind,
|
||||
T,
|
||||
};
|
||||
break;
|
||||
}
|
||||
case "message": {
|
||||
f.T = resolve(desc.message, registry, desc);
|
||||
break;
|
||||
}
|
||||
case "enum": {
|
||||
f.T = resolve(desc.enum, registry, desc);
|
||||
f.default = desc.getDefaultValue();
|
||||
break;
|
||||
}
|
||||
case "scalar": {
|
||||
f.L = desc.longType;
|
||||
f.T = desc.scalar;
|
||||
f.default = desc.getDefaultValue();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return f;
|
||||
}
|
||||
function resolve(desc, registry, context) {
|
||||
const type = desc.kind == "message"
|
||||
? registry.findMessage(desc.typeName)
|
||||
: registry.findEnum(desc.typeName);
|
||||
(0, assert_js_1.assert)(type, `${desc.toString()}" for ${context.toString()} not found`);
|
||||
return type;
|
||||
}
|
||||
Reference in New Issue
Block a user