Skip to content

Commit

Permalink
pw_web: Expose message descriptors and RPC method descriptors
Browse files Browse the repository at this point in the history
Change-Id: I2b1a8ae16c7d08cea7f3d176926b33fef0f6df68
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/107342
Reviewed-by: Anthony DiGirolamo <tonymd@google.com>
Commit-Queue: Asad Memon <asadmemon@google.com>
  • Loading branch information
asadm authored and CQ Bot Account committed Aug 19, 2022
1 parent 29ac193 commit a7a9307
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 8 deletions.
27 changes: 19 additions & 8 deletions pw_protobuf_compiler/ts/proto_collection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,41 +15,42 @@
/** Tools for compiling and importing Javascript protos on the fly. */

import {Message} from 'google-protobuf';
import {FileDescriptorSet} from 'google-protobuf/google/protobuf/descriptor_pb';
import {DescriptorProto, FileDescriptorSet} from 'google-protobuf/google/protobuf/descriptor_pb';

export type MessageCreator = new () => Message;
class MessageMap extends Map<string, MessageCreator> {}
class MessageDescriptorMap extends Map<string, DescriptorProto> { }
export class ModuleMap extends Map<string, any> {}

/**
* A wrapper class of protocol buffer modules to provide convenience methods.
*/
export class ProtoCollection {
private messages: MessageMap;
private messages: MessageMap = new MessageMap();
private messageDescriptors: MessageDescriptorMap = new MessageDescriptorMap();

constructor(
readonly fileDescriptorSet: FileDescriptorSet,
modules: ModuleMap
) {
this.messages = this.mapMessages(fileDescriptorSet, modules);
this.mapMessages(fileDescriptorSet, modules);
}

/**
* Creates a map between message identifier "{packageName}.{messageName}"
* and the Message class.
* and the Message class and also the associated DescriptorProto.
*/
private mapMessages(set: FileDescriptorSet, mods: ModuleMap): MessageMap {
const messages = new MessageMap();
private mapMessages(set: FileDescriptorSet, mods: ModuleMap): void {
for (const fileDescriptor of set.getFileList()) {
const mod = mods.get(fileDescriptor.getName()!)!;
for (const messageType of fileDescriptor.getMessageTypeList()) {
const fullName =
fileDescriptor.getPackage()! + '.' + messageType.getName();
const message = mod[messageType.getName()!];
messages.set(fullName, message);
this.messages.set(fullName, message);
this.messageDescriptors.set(fullName, messageType);
}
}
return messages;
}

/**
Expand All @@ -61,4 +62,14 @@ export class ProtoCollection {
getMessageCreator(identifier: string): MessageCreator | undefined {
return this.messages.get(identifier);
}

/**
* Finds the DescriptorProto referenced by the identifier.
*
* @param identifier String identifier of the form
* "{packageName}.{messageName}" i.e: "pw.rpc.test.NewMessage".
*/
getDescriptorProto(identifier: string): DescriptorProto | undefined {
return this.messageDescriptors.get(identifier);
}
}
16 changes: 16 additions & 0 deletions pw_protobuf_compiler/ts/ts_proto_collection_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,20 @@ describe('ProtoCollection', () => {
fetched = lib.getMessageCreator('pw.test1.Garbage');
expect(fetched).toBeUndefined();
});

it('getDescriptorProto returns descriptor', () => {
const lib = new ProtoCollection();

const fetched = lib.getDescriptorProto('pw.protobuf_compiler.test.Message');
expect(fetched.getFieldList()[0].getName()).toEqual("field");
});

it('getDescriptorProto for invalid identifier returns undefined', () => {
const lib = new ProtoCollection();

let fetched = lib.getMessageCreator('pw');
expect(fetched).toBeUndefined();
fetched = lib.getMessageCreator('pw.test1.Garbage');
expect(fetched).toBeUndefined();
});
});
2 changes: 2 additions & 0 deletions pw_rpc/ts/descriptors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ export class Method {
readonly serverStreaming: boolean;
readonly requestType: any;
readonly responseType: any;
readonly descriptor: MethodDescriptorProto;

constructor(
descriptor: MethodDescriptorProto,
Expand All @@ -87,6 +88,7 @@ export class Method {
this.name = descriptor.getName()!;
this.id = hash(this.name);
this.service = service;
this.descriptor = descriptor;
this.serverStreaming = descriptor.getServerStreaming()!;
this.clientStreaming = descriptor.getClientStreaming()!;

Expand Down

0 comments on commit a7a9307

Please sign in to comment.