diff --git a/packages/proto-loader/src/index.ts b/packages/proto-loader/src/index.ts index c2f203c4..9d1901b1 100644 --- a/packages/proto-loader/src/index.ts +++ b/packages/proto-loader/src/index.ts @@ -379,14 +379,30 @@ export function loadSync( return createPackageDefinition(root, options!); } -export async function loadFileDescriptorSet( - descriptorSet: Protobuf.Message & - descriptor.IFileDescriptorSet, +export function loadFileDescriptorSet( + descriptorSet: + | Buffer + | ReturnType, options?: Options -): Promise { +): PackageDefinition { + type DecodedDescriptorSet = Protobuf.Message & + descriptor.IFileDescriptorSet; + options = options || {}; + + let decodedDescriptorSet: DecodedDescriptorSet; + if (typeof descriptorSet === 'object') { + decodedDescriptorSet = descriptor.FileDescriptorSet.fromObject( + descriptorSet + ) as DecodedDescriptorSet; + } else { + decodedDescriptorSet = descriptor.FileDescriptorSet.decode( + descriptorSet + ) as DecodedDescriptorSet; + } + const root = (Protobuf.Root as Protobuf.RootConstructor).fromDescriptor( - descriptorSet + decodedDescriptorSet ); root.resolveAll(); return createPackageDefinition(root, options); @@ -402,11 +418,7 @@ export function loadFileDescriptorSetFile( return reject(err); } - const descriptorSet = descriptor.FileDescriptorSet.decode( - data - ) as Protobuf.Message & - descriptor.IFileDescriptorSet; - return resolve(loadFileDescriptorSet(descriptorSet, options)); + return resolve(loadFileDescriptorSet(data, options)); }); }); } diff --git a/packages/proto-loader/test/descriptor_type_test.ts b/packages/proto-loader/test/descriptor_type_test.ts index 57eb9ab0..227b7565 100644 --- a/packages/proto-loader/test/descriptor_type_test.ts +++ b/packages/proto-loader/test/descriptor_type_test.ts @@ -16,6 +16,7 @@ */ import * as assert from 'assert'; +import { rpcFileDescriptorSet } from '../test_protos/rpc.desc'; import * as proto_loader from '../src/index'; @@ -101,7 +102,12 @@ describe('Descriptor types', () => { }); it('Can load binary-encoded proto file descriptor sets', () => { - // This will throw if the well known protos are not available. + // This will throw if the rpc descriptor cannot be decoded proto_loader.loadFileDescriptorSetFile(`${TEST_PROTO_DIR}/rpc.desc`); }); + + it('Can parse plain file descriptor set objects', () => { + // This will throw if the file descriptor object cannot be parsed + proto_loader.loadFileDescriptorSet(rpcFileDescriptorSet); + }); }); diff --git a/packages/proto-loader/test_protos/rpc.desc.ts b/packages/proto-loader/test_protos/rpc.desc.ts new file mode 100644 index 00000000..7e52ea0d --- /dev/null +++ b/packages/proto-loader/test_protos/rpc.desc.ts @@ -0,0 +1,46 @@ +export const rpcFileDescriptorSet = { + "file": [ + { + "name": "test_protos/rpc.proto", + "messageType": [ + { + "name": "MyRequest", + "field": [ + { + "name": "path", + "number": 1, + "label": "LABEL_OPTIONAL", + "type": "TYPE_STRING", + "jsonName": "path" + } + ] + }, + { + "name": "MyResponse", + "field": [ + { + "name": "status", + "number": 2, + "label": "LABEL_OPTIONAL", + "type": "TYPE_INT32", + "jsonName": "status" + } + ] + } + ], + "service": [ + { + "name": "MyService", + "method": [ + { + "name": "MyMethod", + "inputType": ".MyRequest", + "outputType": ".MyResponse" + } + ] + } + ], + "syntax": "proto3" + } + ] +}