Skip to content

Commit

Permalink
Add support for jstype annotation
Browse files Browse the repository at this point in the history
Required an upgrade to google-protobuf 3.6.1, otherwise very straight forward.

Fixes #17
  • Loading branch information
jonny-improbable committed Aug 31, 2018
1 parent 50bb30c commit 9bd2372
Show file tree
Hide file tree
Showing 10 changed files with 237 additions and 6 deletions.
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -172,3 +172,12 @@ client.getUser(req, (err, user) => { /* ... */ });
For a sample of the generated protos and service definitions, see [examples](https://github.com/improbable-eng/ts-protoc-gen/tree/master/examples).

To generate the examples from protos, please run `./generate.sh`

## Gotchas
By default the google-protobuf library will use the JavaScript number type to store 64bit float and integer values; this can lead to overflow problems as you exceed JavaScript's `Number.MAX_VALUE`. To work around this, you should consider using the `jstype` annotation on any 64bit fields, ie:

```proto
message Example {
uint64 bigInt = 1 [jstype = JS_STRING];
}
```
25 changes: 25 additions & 0 deletions examples/generated/proto/examplecom/annotations_pb.d.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

157 changes: 157 additions & 0 deletions examples/generated/proto/examplecom/annotations_pb.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions examples/generated/proto/examplecom/annotations_pb_service.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
"author": "Improbable",
"license": "Apache-2.0",
"dependencies": {
"google-protobuf": "^3.5.0"
"google-protobuf": "^3.6.1"
},
"devDependencies": {
"@types/chai": "^3.5.2",
Expand Down
7 changes: 7 additions & 0 deletions proto/examplecom/annotations.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
syntax = "proto3";

package examplecom;

message AnnotatedMessage {
uint64 bigInt = 1 [jstype = JS_STRING];
}
21 changes: 19 additions & 2 deletions src/ts/message.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,16 @@ import {
withinNamespaceFromExportEntry, normaliseFieldObjectName
} from "../util";
import {ExportMap} from "../ExportMap";
import {FieldDescriptorProto, FileDescriptorProto, DescriptorProto} from "google-protobuf/google/protobuf/descriptor_pb";
import {
FieldDescriptorProto, FileDescriptorProto, DescriptorProto,
FieldOptions
} from "google-protobuf/google/protobuf/descriptor_pb";
import {MESSAGE_TYPE, BYTES_TYPE, ENUM_TYPE, getFieldType, getTypeName} from "./FieldTypes";
import {Printer} from "../Printer";
import {printEnum} from "./enum";
import {printOneOfDecl} from "./oneof";
import {printExtension} from "./extensions";
import JSType = FieldOptions.JSType;

function hasFieldPresence(field: FieldDescriptorProto, fileDescriptor: FileDescriptorProto): boolean {
if (field.getLabel() === FieldDescriptorProto.Label.LABEL_REPEATED) {
Expand Down Expand Up @@ -104,7 +108,20 @@ export function printMessage(fileName: string, exportMap: ExportMap, messageDesc
exportType = filePathToPseudoNamespace(fieldEnumType.fileName) + "." + withinNamespace;
}
} else {
exportType = getTypeName(type);
if (field.getOptions() && field.getOptions().hasJstype()) {
switch (field.getOptions().getJstype()) {
case JSType.JS_NUMBER:
exportType = "number";
break;
case JSType.JS_STRING:
exportType = "string";
break;
default:
exportType = getTypeName(type);
}
} else {
exportType = getTypeName(type);
}
}

let hasClearMethod = false;
Expand Down
10 changes: 10 additions & 0 deletions test/integration/annotations.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { assert } from "chai";
import { AnnotatedMessage } from "../../examples/generated/proto/examplecom/annotations_pb";

describe("annotations", () => {
it("should detect and honor the `jstype` annotation", () => {
const msg = new AnnotatedMessage();
msg.setBigint("123456789123456789");
assert.strictEqual(msg.getBigint(), "123456789123456789");
});
});

0 comments on commit 9bd2372

Please sign in to comment.