mirror of https://github.com/grpc/grpc-node.git
Merge pull request #1635 from tatemz/feature/load-file-descriptor-sets
Add functions for loading and parsing binary-encoded or plain object file descriptor sets
This commit is contained in:
commit
604dd0f206
|
@ -30,6 +30,17 @@ declare module 'protobufjs' {
|
|||
descriptor.IDescriptorProto;
|
||||
}
|
||||
|
||||
interface RootConstructor {
|
||||
new (options?: Options): Root;
|
||||
fromDescriptor(
|
||||
descriptorSet:
|
||||
| descriptor.IFileDescriptorSet
|
||||
| Protobuf.Reader
|
||||
| Uint8Array
|
||||
): Root;
|
||||
fromJSON(json: Protobuf.INamespace, root?: Root): Root;
|
||||
}
|
||||
|
||||
interface Root {
|
||||
toDescriptor(
|
||||
protoVersion: string
|
||||
|
@ -98,6 +109,9 @@ export type Options = Protobuf.IParseOptions &
|
|||
includeDirs?: string[];
|
||||
};
|
||||
|
||||
type DecodedDescriptorSet = Protobuf.Message<descriptor.IFileDescriptorSet> &
|
||||
descriptor.IFileDescriptorSet;
|
||||
|
||||
const descriptorOptions: Protobuf.IConversionOptions = {
|
||||
longs: String,
|
||||
enums: String,
|
||||
|
@ -307,6 +321,19 @@ function addIncludePathResolver(root: Protobuf.Root, includePaths: string[]) {
|
|||
};
|
||||
}
|
||||
|
||||
function createPackageDefinitionFromDescriptorSet(
|
||||
decodedDescriptorSet: DecodedDescriptorSet,
|
||||
options?: Options
|
||||
) {
|
||||
options = options || {};
|
||||
|
||||
const root = (Protobuf.Root as Protobuf.RootConstructor).fromDescriptor(
|
||||
decodedDescriptorSet
|
||||
);
|
||||
root.resolveAll();
|
||||
return createPackageDefinition(root, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a .proto file with the specified options.
|
||||
* @param filename One or multiple file paths to load. Can be an absolute path
|
||||
|
@ -368,6 +395,34 @@ export function loadSync(
|
|||
return createPackageDefinition(root, options!);
|
||||
}
|
||||
|
||||
export function loadFileDescriptorSetFromBuffer(
|
||||
descriptorSet: Buffer,
|
||||
options?: Options
|
||||
): PackageDefinition {
|
||||
const decodedDescriptorSet = descriptor.FileDescriptorSet.decode(
|
||||
descriptorSet
|
||||
) as DecodedDescriptorSet;
|
||||
|
||||
return createPackageDefinitionFromDescriptorSet(
|
||||
decodedDescriptorSet,
|
||||
options
|
||||
);
|
||||
}
|
||||
|
||||
export function loadFileDescriptorSetFromObject(
|
||||
descriptorSet: Parameters<typeof descriptor.FileDescriptorSet.fromObject>[0],
|
||||
options?: Options
|
||||
): PackageDefinition {
|
||||
const decodedDescriptorSet = descriptor.FileDescriptorSet.fromObject(
|
||||
descriptorSet
|
||||
) as DecodedDescriptorSet;
|
||||
|
||||
return createPackageDefinitionFromDescriptorSet(
|
||||
decodedDescriptorSet,
|
||||
options
|
||||
);
|
||||
}
|
||||
|
||||
// Load Google's well-known proto files that aren't exposed by Protobuf.js.
|
||||
|
||||
// Protobuf.js exposes: any, duration, empty, field_mask, struct, timestamp,
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
*/
|
||||
|
||||
import * as assert from 'assert';
|
||||
import { rpcFileDescriptorSet } from '../test_protos/rpc.desc';
|
||||
import { readFileSync } from 'fs';
|
||||
|
||||
import * as proto_loader from '../src/index';
|
||||
|
||||
|
@ -99,4 +101,22 @@ describe('Descriptor types', () => {
|
|||
// This will throw if the well known protos are not available.
|
||||
proto_loader.loadSync(`${TEST_PROTO_DIR}/well_known.proto`);
|
||||
});
|
||||
|
||||
it('Can load binary-encoded proto file descriptor sets', () => {
|
||||
const buffer = readFileSync(`${TEST_PROTO_DIR}/rpc.desc.bin`);
|
||||
// This will throw if the rpc descriptor cannot be decoded
|
||||
proto_loader.loadFileDescriptorSetFromBuffer(buffer);
|
||||
});
|
||||
|
||||
it('Can load json file descriptor sets', () => {
|
||||
const buffer = readFileSync(`${TEST_PROTO_DIR}/rpc.desc.json`);
|
||||
const json = JSON.parse(buffer.toString());
|
||||
// This will throw if the rpc descriptor JSON cannot be decoded
|
||||
proto_loader.loadFileDescriptorSetFromObject(json);
|
||||
});
|
||||
|
||||
it('Can parse plain file descriptor set objects', () => {
|
||||
// This will throw if the file descriptor object cannot be parsed
|
||||
proto_loader.loadFileDescriptorSetFromObject(rpcFileDescriptorSet);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
|
||||
˜
|
||||
test_protos/rpc.proto"
|
||||
MyRequest
|
||||
path ( Rpath"$
|
||||
|
||||
MyResponse
|
||||
status (Rstatus20
|
||||
MyService#
|
||||
MyMethod
|
||||
.MyRequest.MyResponsebproto3
|
|
@ -0,0 +1,46 @@
|
|||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -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"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
syntax = "proto3";
|
||||
|
||||
service MyService {
|
||||
rpc MyMethod (MyRequest) returns (MyResponse);
|
||||
}
|
||||
|
||||
message MyRequest {
|
||||
string path = 1;
|
||||
}
|
||||
|
||||
message MyResponse {
|
||||
int32 status = 2;
|
||||
}
|
Loading…
Reference in New Issue