|
| 1 | + |
| 2 | +# JavaScript Generated Code |
| 3 | + |
| 4 | +This page describes exactly what JavaScript code the protocol buffer compiler |
| 5 | +generates for any given protocol definition. Any differences between proto2 and |
| 6 | +proto3 generated code are highlighted. You should read the |
| 7 | +[proto2 language guide](https://developers.google.com/protocol-buffers/docs/proto) and/or the |
| 8 | +[proto3 language guide](https://developers.google.com/protocol-buffers/docs/proto3) before reading this document. |
| 9 | + |
| 10 | +## Compiler Invocation |
| 11 | +The protocol buffer compiler produces JavaScript output when invoked with the |
| 12 | +`--js_out=` command-line flag. The parameter to the `--js_out=` option is the |
| 13 | +directory where you want the compiler to write your JavaScript output. The exact |
| 14 | +output depends on whether you want to use Closure-style imports or |
| 15 | +CommonJS-style imports; the compiler supports both. |
| 16 | + |
| 17 | +**Note:** Support for ES6-style imports is not implemented yet. Browsers can be supported by using Browserify, webpack, Closure Compiler, or similar to resolve imports at compile time. |
| 18 | + |
| 19 | +### Closure Imports |
| 20 | +By default, the compiler generates code with Closure-style imports. If you |
| 21 | +specify a `library` option when running the compiler, the compiler creates a |
| 22 | +single `.js` file with your specified library name. Otherwise the compiler |
| 23 | +generates a `.js` file for each *message* in your `.proto` file. The names of |
| 24 | +the output files are computed by taking the `library` value or message name |
| 25 | +(lowercased), with the following changes. |
| 26 | + |
| 27 | +So, for example, let's say you invoke the compiler as follows: |
| 28 | + |
| 29 | +``` |
| 30 | +protoc --plugin=protoc-gen-js=/path/to/protobuf-javascript/bazel-bin/generator/protoc-gen-js --proto_path=src --js_out=library=whizz/ponycopter,binary:build/gen src/foo.proto src/bar/baz.proto |
| 31 | +``` |
| 32 | + |
| 33 | +The compiler will read the files `src/foo.proto` and `src/bar/baz.proto` and |
| 34 | +produce a single output file, `build/gen/whizz/ponycopter.js`. The compiler will |
| 35 | +automatically create the directory `build/gen/whizz` if necessary, but it will |
| 36 | +*not* create `build` or `build/gen`; they must already exist. |
| 37 | +The generated file(s) `goog.provide()` all 'the types defined in your `.proto` |
| 38 | +file(s), and `goog.require()` many types in the core protocol buffers library |
| 39 | +and Google Closure library. Make sure that your `goog.provide()` / |
| 40 | +`goog.require()` setup can find all of your generated code, |
| 41 | +[the core library `.js` files](https://github.com/protocolbuffers/protobuf-javascript) |
| 42 | +and the Google Closure library itself. |
| 43 | + |
| 44 | +You should be able to import your generated types with statements like: |
| 45 | + |
| 46 | +```js |
| 47 | +goog.require('proto.my.package.MyMessage'); |
| 48 | +const message = proto.my.package.MyMessage(); |
| 49 | +``` |
| 50 | + |
| 51 | +### CommonJS Imports |
| 52 | +To specify that you want to use CommonJS-style imports instead of the default |
| 53 | +Closure style, you run the compiler with the `import_style=commonjs` option. The |
| 54 | +names of the output files are computed by taking the name of the each input |
| 55 | +`.proto` file and making two changes. |
| 56 | + |
| 57 | +**Note:** Specifying a `library` option is ignored with this import style. |
| 58 | + |
| 59 | +So, for example, let's say you invoke the compiler as follows: |
| 60 | + |
| 61 | +``` |
| 62 | +protoc --plugin=protoc-gen-js=/path/to/protobuf-javascript/bazel-bin/generator/protoc-gen-js --proto_path=src --js_out=import_style=commonjs,binary:build/gen src/foo.proto src/bar/baz.proto |
| 63 | +``` |
| 64 | + |
| 65 | +The compiler will read the files `src/foo.proto` and `src/bar/baz.proto` and |
| 66 | +produce two output files: `build/gen/foo_pb.js` and `build/gen/bar/baz_pb.js`. |
| 67 | +The compiler will automatically create the directory `build/gen/bar` if |
| 68 | +necessary, but it will *not* create `build` or `build/gen`; they must already |
| 69 | +exist. |
| 70 | + |
| 71 | +The generated code depends on the core runtime, which should be in a file |
| 72 | +called `google-protobuf.js`. If you installed protoc via `npm`, this file should |
| 73 | +already be built and available. If you are running from GitHub, you need to |
| 74 | +build it first by running: |
| 75 | + |
| 76 | +``` |
| 77 | +PROTOC=/path/to/protoc PROTOC_INC=/path/to/proto/include gulp dist |
| 78 | +``` |
| 79 | + |
| 80 | +You should be able to import your generated types with statements like: |
| 81 | + |
| 82 | +```js |
| 83 | +const messages = require('./messages_pb'); |
| 84 | +const message = new messages.MyMessage(); |
| 85 | +``` |
| 86 | + |
| 87 | +### Compiler Options |
| 88 | +The protocol buffer compiler for JavaScript has many options to customize its |
| 89 | +output in addition to the `library` and `import_style` options mentioned above. |
| 90 | +For example: |
| 91 | + |
| 92 | +* `binary`: Using this option generates code that lets you serialize and deserialize your proto from the protocol buffers binary wire format. We recommend that you enable this option. |
| 93 | + `--js_out=library=myprotos_lib.js,binary:.` |
| 94 | + |
| 95 | +As in the above examples, multiple options can be specified, separated by commas. You can see a complete list of available options in [js_generator.h](https://github.com/protocolbuffers/protobuf-javascript/blob/59a828fc713538404dcc9de8f42b4abfcfa5eb7d/generator/js_generator.h#L62-L76). |
| 96 | + |
| 97 | +## Packages |
| 98 | +### Packages and Closure Imports |
| 99 | +If you are using Closure-style imports and a `.proto` file contains a package |
| 100 | +declaration, the generated code uses the proto's `package` as part of the |
| 101 | +JavaScript namespace for your message types. For example, a proto package name |
| 102 | +of `example.high_score` results in a JavaScript namespace of `proto.example.high_score`. |
| 103 | + |
| 104 | +```js |
| 105 | +goog.provide('proto.example.high_score.Ponycopter'); |
| 106 | +``` |
| 107 | + |
| 108 | +Otherwise, if a `.proto` file does not contain a package declaration, the |
| 109 | +generated code just uses `proto` as the namespace for your message types, which |
| 110 | +is the root of the protocol buffers namespace. |
| 111 | + |
| 112 | +### Packages and CommonJS Imports |
| 113 | +If you are using CommonJS-style imports, any package declarations in your |
| 114 | +`.proto` files are ignored by the compiler. |
| 115 | + |
| 116 | +## Messages |
| 117 | +Given a simple message declaration: |
| 118 | + |
| 119 | +```protobuf |
| 120 | +message Foo {} |
| 121 | +``` |
| 122 | + |
| 123 | +the protocol buffer compiler generates a class called `Foo`. `Foo` inherits |
| 124 | +from [`jspb.Message`](https://github.com/protocolbuffers/protobuf-javascript/blob/59a828fc713538404dcc9de8f42b4abfcfa5eb7d/message.js). |
| 125 | + |
| 126 | +You should *not* create your own `Foo` subclasses. Generated classes are not |
| 127 | +designed for subclassing and may lead to "fragile base class" problems. |
| 128 | + |
| 129 | +Your generated class has accessors for all its fields (which we'll look at in |
| 130 | +the following sections) and the following methods that apply to the entire |
| 131 | +message: |
| 132 | + |
| 133 | +* `toObject()`: Returns an object representation of the message, suitable for use in Soy templates. This method comes in static and instance versions. Field names that are [reserved in JavaScript]("http://www.w3schools.com/js/js_reserved.asp") are renamed to `pb_name`. If you don't want to generate this method (for instance, if you're not going to use it and are concerned about code size), set [jspb.Message.GENERATE_TO_OBJECT](https://github.com/protocolbuffers/protobuf-javascript/blob/59a828fc713538404dcc9de8f42b4abfcfa5eb7d/message.js#L174) to false before code generation. Note that this representation is not the same as [proto3's JSON representation](https://developers.google.com/protocol-buffers/docs/proto3#json). |
| 134 | +* `clone()`: Creates a deep clone of this message and its fields. |
| 135 | + |
| 136 | +The following methods are also provided if you have enabled the `binary` |
| 137 | +option when generating your code: |
| 138 | + |
| 139 | +* `deserializeBinary()`: Static method. Deserializes a message from protocol buffers binary wire format and returns a new populated message object. Does not preserve any unknown fields in the binary message. |
| 140 | +* `deserializeBinaryFromReader()`: Static method. Deserializes a message in protocol buffers binary wire format from the provided [BinaryReader](https://github.com/protocolbuffers/protobuf-javascript/blob/59a828fc713538404dcc9de8f42b4abfcfa5eb7d/binary/reader.js) into the provided message object. Does not preserve any unknown fields in the binary message. |
| 141 | +* `serializeBinary()`: Serializes this message to protocol buffers binary wire format. |
| 142 | +* `serializeBinaryToWriter()`: Serializes this message in protocol buffers binary wire format to the specified [BinaryWriter](https://github.com/protocolbuffers/protobuf-javascript/blob/59a828fc713538404dcc9de8f42b4abfcfa5eb7d/binary/writer.js). This method has a static variant where you can serialize a specified message to the BinaryWriter. |
| 143 | + |
| 144 | + |
| 145 | +## Fields |
| 146 | +The protocol buffer compiler generates accessors for each field in your |
| 147 | +protocol buffer message. The exact accessors depend on its type and whether it |
| 148 | +is a singular, repeated, map, or oneof field. |
| 149 | + |
| 150 | +Note that the generated accessors always use camel-case naming, even if the |
| 151 | +field name in the `.proto` file uses lower-case with underscores |
| 152 | +([as it should](https://developers.google.com/protocol-buffers/docs/style)). The case-conversion works as |
| 153 | +follows: |
| 154 | + |
| 155 | +The proto field `foo_bar_baz` has, for example, a `getFooBarBaz()` method. |
| 156 | + |
| 157 | + |
| 158 | +### Singular Scalar Fields (proto2) |
| 159 | +For either of these field definitions: |
| 160 | + |
| 161 | +```protobuf |
| 162 | +optional int32 foo = 1; |
| 163 | +required int32 foo = 1; |
| 164 | +``` |
| 165 | + |
| 166 | +the compiler generates the following instance methods: |
| 167 | + |
| 168 | +* `setFoo()`: Set the value of `foo`. |
| 169 | +* `getFoo()`: Get the value of `foo`. If the field has not been set, returns the default value for its type. |
| 170 | +* `hasFoo()`: Returns `true` if this field has been set. |
| 171 | +* `clearFoo()`: Clears the value of this field: after this has been called `hasFoo()` returns `false` and `getFoo()` returns the default value. |
| 172 | + |
| 173 | +Similar methods are generated for any of protocol buffers' |
| 174 | +[scalar types](https://developers.google.com/protocol-buffers/docs/proto#scalar). |
| 175 | + |
| 176 | +### Singular Scalar Fields (proto3) |
| 177 | +For this field definition: |
| 178 | + |
| 179 | +```protobuf |
| 180 | +int32 foo = 1; |
| 181 | +``` |
| 182 | + |
| 183 | +the compiler generates the following instance methods: |
| 184 | + |
| 185 | +* `setFoo()`: Set the value of `foo`. |
| 186 | +* `getFoo()`: Get the value of `foo`. |
| 187 | + |
| 188 | + |
| 189 | +Similar methods are generated for any of protocol buffers' |
| 190 | +[scalar types](https://developers.google.com/protocol-buffers/docs/proto3). |
| 191 | + |
| 192 | + |
| 193 | +### Bytes Fields |
| 194 | +For this field definition: |
| 195 | + |
| 196 | +```protobuf |
| 197 | +bytes foo = 1; |
| 198 | +``` |
| 199 | + |
| 200 | +the compiler generates the same methods as for other scalar value types. The |
| 201 | +`set..` method accepts either a base-64 encoded string or a `Uint8Array`. The |
| 202 | +`get..` method returns whichever representation was set last. However, there are |
| 203 | +also special methods generated that allow you to coerce the returned |
| 204 | +representation to your preferred version: |
| 205 | + |
| 206 | +* `getFoo_asB64()`: Returns the value of `foo` as a base-64 encoded string. |
| 207 | +* `getFoo_asU8()`: Returns the value of `foo` as a `Uint8Array`. |
| 208 | + |
| 209 | +### Singular Message Fields |
| 210 | +Given the message type: |
| 211 | + |
| 212 | +```protobuf |
| 213 | +message Bar {} |
| 214 | +``` |
| 215 | + |
| 216 | +For a message with a `Bar` field: |
| 217 | + |
| 218 | +```protobuf |
| 219 | +// proto2 |
| 220 | +message Baz { |
| 221 | + optional Bar foo = 1; |
| 222 | + // The generated code is the same result if required instead of optional. |
| 223 | +} |
| 224 | +
|
| 225 | +// proto3 |
| 226 | +message Baz { |
| 227 | + Bar foo = 1; |
| 228 | +} |
| 229 | +``` |
| 230 | + |
| 231 | +the compiler generates the following instance methods: |
| 232 | + |
| 233 | +* `setFoo()`: Set the value of `foo`. When called with `undefined`, it is equivalent to calling `clearFoo()`. |
| 234 | +* `getFoo()`: Get the value of `foo`. Returns `undefined` if the field has not been set. |
| 235 | +* `hasFoo()`: Returns `true` if this field has been set. Equivalent to `!!getFoo()`. |
| 236 | +* `clearFoo()`: Clears the value of this field to `undefined`. |
| 237 | + |
| 238 | +### Repeated Fields |
| 239 | +For this message with a repeated field: |
| 240 | + |
| 241 | +```protobuf |
| 242 | +message Baz { |
| 243 | + repeated int32 foo = 1; |
| 244 | +} |
| 245 | +``` |
| 246 | + |
| 247 | +the compiler generates the following instance methods: |
| 248 | + |
| 249 | +* `setFooList()`: Set the value of `foo` to the specified JavaScript array. Returns the message itself for chaining. |
| 250 | +* `addFoo()`: Appends a value of `foo` to the end of the list of foos that was in the message. Returns the outer message for chaining **only if** the added value was a primitive. For added messages, returns the message that was added. |
| 251 | +* `getFooList()`: Gets the value of `foo` as a JavaScript array. The returned array is never `undefined` and each element is never `undefined`. You should **no** mutate the list returned from this method. |
| 252 | +* `clearFooList()`: Clears the value of this field to `[]`. |
| 253 | + |
| 254 | + |
| 255 | +### Map Fields |
| 256 | +For this message with a map field: |
| 257 | + |
| 258 | +```protobuf |
| 259 | +message Bar {} |
| 260 | +
|
| 261 | +message Baz { |
| 262 | + map<string, Bar> foo = 1; |
| 263 | +} |
| 264 | +``` |
| 265 | + |
| 266 | +the compiler generates the following instance method: |
| 267 | + |
| 268 | +* `getFooMap()`: Returns the [Map](https://github.com/protocolbuffers/protobuf-javascript/blob/59a828fc713538404dcc9de8f42b4abfcfa5eb7d/map.js) containing `foo`'s key-value pairs. You can then use `Map` methods to interact with the map. |
| 269 | + |
| 270 | +### Oneof Fields |
| 271 | +For this message with a oneof field: |
| 272 | + |
| 273 | +```protobuf |
| 274 | +package account; |
| 275 | +
|
| 276 | +message Profile { |
| 277 | + oneof avatar { |
| 278 | + string image_url = 1; |
| 279 | + bytes image_data = 2; |
| 280 | + } |
| 281 | +} |
| 282 | +``` |
| 283 | + |
| 284 | +The class corresponding to `Profile` will have accessor methods just like regular fields (`getImageUrl()`, `getImageData()`). However, unlike regular fields, at most one of the fields in a oneof can be set at a time, so setting one field will clear the others. Also note that if you are using proto3, the compiler generates `has..` and `clear..` accessors for oneof fields, even for scalar types. |
| 285 | + |
| 286 | +In addition to the regular accessor methods, the compiler generates a special method to check which field in the oneof is set: for our example, the method is `getAvatarCase()`. The possible return values for this are defined in the `AvatarCase` enum: |
| 287 | + |
| 288 | +```js |
| 289 | +proto.account.Profile.AvatarCase = { |
| 290 | + AVATAR_NOT_SET: 0, |
| 291 | + IMAGE_URL: 1, |
| 292 | + IMAGE_DATA: 2 |
| 293 | +}; |
| 294 | +``` |
| 295 | + |
| 296 | +## Enumerations |
| 297 | +Given an enumeration like: |
| 298 | + |
| 299 | +```protobuf |
| 300 | +message SearchRequest { |
| 301 | + enum Corpus { |
| 302 | + UNIVERSAL = 0; |
| 303 | + WEB = 1; |
| 304 | + IMAGES = 2; |
| 305 | + LOCAL = 3; |
| 306 | + NEWS = 4; |
| 307 | + PRODUCTS = 5; |
| 308 | + VIDEO = 6; |
| 309 | + } |
| 310 | + Corpus corpus = 1; |
| 311 | + ... |
| 312 | +} |
| 313 | +``` |
| 314 | + |
| 315 | +the protocol buffer compiler generates a corresponding JavaScript enum. |
| 316 | + |
| 317 | +```js |
| 318 | +proto.SearchRequest.Corpus = { |
| 319 | + UNIVERSAL: 0, |
| 320 | + WEB: 1, |
| 321 | + IMAGES: 2, |
| 322 | + LOCAL: 3, |
| 323 | + NEWS: 4, |
| 324 | + PRODUCTS: 5, |
| 325 | + VIDEO: 6 |
| 326 | +}; |
| 327 | +``` |
| 328 | + |
| 329 | +The compiler also generates getters and setters for enum fields, just like |
| 330 | +regular singular scalar fields. Note that in proto3, you can set an enum field |
| 331 | +to any value. In proto2, you should provide one of the specified enum values. |
| 332 | + |
| 333 | +## Any |
| 334 | +Given an [`Any`](/protocol-buffers/docs/proto3#any) field like this: |
| 335 | + |
| 336 | +```protobuf |
| 337 | +import "google/protobuf/any.proto"; |
| 338 | +
|
| 339 | +package foo; |
| 340 | +
|
| 341 | +message Bar {} |
| 342 | +
|
| 343 | +message ErrorStatus { |
| 344 | + string message = 1; |
| 345 | + google.protobuf.Any details = 2; |
| 346 | +} |
| 347 | +``` |
| 348 | + |
| 349 | +In our generated code, the getter for the `details` field returns an instance of `proto.google.protobuf.Any`. This provides the following special methods: |
| 350 | + |
| 351 | +```js |
| 352 | +/** |
| 353 | + * Returns the fully qualified proto name of the packed message, if any. |
| 354 | + * @return {string|undefined} |
| 355 | + */ |
| 356 | +proto.google.protobuf.Any.prototype.getTypeName; |
| 357 | +/** |
| 358 | + * Packs the given message instance into this Any. |
| 359 | + * @param {!Uint8Array} serialized The serialized data to pack. |
| 360 | + * @param {string} name The fully qualified proto name of the packed message. |
| 361 | + * @param {string=} opt_typeUrlPrefix the type URL prefix. |
| 362 | + */ |
| 363 | +proto.google.protobuf.Any.prototype.pack; |
| 364 | +/** |
| 365 | + * @template T |
| 366 | + * Unpacks this Any into the given message object. |
| 367 | + * @param {function(Uint8Array):T} deserialize Function that will deserialize |
| 368 | + * the binary data properly. |
| 369 | + * @param {string} name The expected type name of this message object. |
| 370 | + * @return {?T} If the name matched the expected name, returns the deserialized |
| 371 | + * object, otherwise returns null. |
| 372 | + */ |
| 373 | +proto.google.protobuf.Any.prototype.unpack; |
| 374 | +``` |
| 375 | + |
| 376 | +Example: |
| 377 | + |
| 378 | +```js |
| 379 | +// Storing an arbitrary message type in Any. |
| 380 | +const status = new proto.foo.ErrorStatus(); |
| 381 | +const any = new Any(); |
| 382 | +const binarySerialized = ...; |
| 383 | +any.pack(binarySerialized, 'foo.Bar'); |
| 384 | +console.log(any.getTypeName()); // foo.Bar |
| 385 | +// Reading an arbitrary message from Any. |
| 386 | +const bar = any.unpack(proto.foo.Bar.deserializeBinary, 'foo.Bar'); |
| 387 | +``` |
| 388 | + |
0 commit comments