You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
**Note** that this library's versioning scheme is not semver-compatible for historical reasons. For guaranteed backward compatibility, always depend on `~6.A.B` instead of `^6.A.B` (hence the `--save-prefix` above).
**NOTE:** Remember to replace the version tag with the exact [release](https://github.com/dcodeIO/protobuf.js/tags) your project depends upon.
82
+
**Remember** to replace the version tag with the exact [release](https://github.com/dcodeIO/protobuf.js/tags) your project depends upon.
75
83
76
-
The `protobuf` namespace will always be available globally / also supports AMD loaders.
84
+
The library supports CommonJS and AMD loaders and also exports globally as `protobuf`.
77
85
78
86
### Distributions
79
87
80
-
The library supports both reflection-based and code-based use cases:
88
+
Where bundle size is a factor, there are additional stripped-down versions of the [full library][dist-full] (~19kb gzipped) available that exclude certain functionality:
81
89
82
-
1. Parsing protocol buffer definitions (.proto files) to reflection
83
-
2. Loading JSON descriptors to reflection
84
-
3. Generating static code without any reflection features
90
+
* When working with JSON descriptors (i.e. generated by [pbjs](#pbjs-for-javascript)) and/or reflection only, see the [light library][dist-light] (~16kb gzipped) that excludes the parser. CommonJS entry point is:
85
91
86
-
Where bundle size is a factor, there is a suitable distribution for each of these:
92
+
```js
93
+
var protobuf =require("protobufjs/light");
94
+
```
87
95
88
-
| | Gzipped | Downloads | How to require | Description
| full | 18.5kb | [dist][dist-full] | `require("protobufjs")` | All features. Works with everything.
91
-
| light | 15.5kb | [dist/light][dist-light] | `require("protobufjs/light")` | All features except tokenizer, parser and bundled common types. Works with JSON definitions, pure reflection and static code.
92
-
| minimal | 6.0kb+ | [dist/minimal][dist-minimal] | `require("protobufjs/minimal")` | Just enough to run static code. No reflection.
96
+
* When working with statically generated code only, see the [minimal library][dist-minimal] (~6.5kb gzipped) that also excludes reflection. CommonJS entry point is:
93
97
94
-
In case of doubt it is safe to just use the full library.
@@ -100,12 +106,43 @@ In case of doubt it is safe to just use the full library.
100
106
Usage
101
107
-----
102
108
103
-
Each message type provides a set of methods with each method doing just one thing. This avoids unnecessary operations where [performance](#performance) is a concern but also forces a user to perform verification explicitly where necessary - for example when dealing with user input.
109
+
Because JavaScript is a dynamically typed language, protobuf.js introduces the concept of a **valid message** in order to provide the best possible [performance](#performance):
110
+
111
+
### Valid message
112
+
113
+
> **A valid message is an object not missing any required fields and exclusively using JS types for its fields (properties) that are understood by the wire format writer.**
114
+
115
+
There are two possible types of valid messages and the encoder is able to work with both of these:
116
+
117
+
***Runtime messages** (explicit instances of message classes with default values on their prototype) always (have to) satisfy the requirements of a valid message and
118
+
***Plain JavaScript objects** that just so happen to be composed in a way satisfying the requirements of a valid message as well.
119
+
120
+
In a nutshell, the wire format writer understands the following types:
121
+
122
+
| Field type | Expected JS type (create, encode) | Naive conversion (fromObject)
| s-/u-/int32<br />s-/fixed32 | `number` (32 bit integer) | `value | 0` if signed<br /> `value >>> 0` if unsigned
125
+
| s-/u-/int64<br />s-/fixed64 | `Long`-like (optimal)<br />`number` (53 bit integer) | `Long.fromValue(value)` with long.js<br />`parseInt(value, 10)` otherwise
126
+
| float<br />double | `number` | `Number(value)`
127
+
| bool | `boolean` | `Boolean(value)`
128
+
| string | `string` | `String(value)`
129
+
| bytes | `Uint8Array` (optimal)<br />`Buffer` (optimal under node)<br />`Array.<number>` (8 bit integers) | `base64.decode(value)` if a `string`<br />`Object` with non-zero `.length` is assumed to be buffer-like
130
+
| enum | `number` (32 bit integer) | Looks up the numeric id if a `string`
* Explicit `undefined` and `null` are considered as not set if the field is optional.
134
+
* Repeated fields are `Array.<T>`.
135
+
* Map fields are `Object.<string,T>` with the key being the string representation of the respective value or an 8 characters long binary hash string for `Long`-likes.
136
+
* Types marked as *optimal* provide the best performance because no conversion step (i.e. number to low and high bits or base64 string to buffer) is required.
137
+
138
+
### Toolset
104
139
105
-
Note that **Message** below refers to any message type. See the next section for the definition of a [valid message](#valid-message).
140
+
With that in mind and again for performance reasons, each message class provides a distinct set of methods with each method doing just one thing. This avoids unnecessary assertions / operations where performance is a concern but also forces a user to perform verification (of plain JavaScript objects that *might* just so happen to be a valid message) explicitly where necessary - for example when dealing with user input.
141
+
142
+
**Note** that `Message` below refers to any message class.
explicitly performs verification prior to encoding a plain object. Instead of throwing, it returns the error message as a string, if any.
145
+
verifies that a **plain JavaScript object** satisfies the requirements of a valid message and thus can be encoded without issues. Instead of throwing, it returns the error message as a string, if any.
109
146
110
147
```js
111
148
var payload ="invalid (not an object)";
@@ -115,7 +152,7 @@ Note that **Message** below refers to any message type. See the next section for
is an automatically generated message specific encoder expecting a valid message or plain object. Note that this method does not implicitly verify the message and that it's up to the user to make sure that the data can actually be encoded properly.
155
+
encodes a valid message (**runtime message** or valid **plain JavaScript object**). This method does not implicitly verify the message and it's up to the user to make sure that the payload is a valid message.
119
156
120
157
```js
121
158
var buffer =AwesomeMessage.encode(message).finish();
@@ -125,7 +162,7 @@ Note that **Message** below refers to any message type. See the next section for
125
162
works like `Message.encode` but additionally prepends the length of the message as a varint.
is an automatically generated message specific decoder. If required fields are missing, it throws a `util.ProtocolError` with an `instance` property set to the so far decoded message. If the wire format is invalid, it throws an `Error`. The result is a runtime message.
165
+
decodes a buffer to a **runtime message**. If required fields are missing, it throws a `util.ProtocolError` with an `instance` property set to the so far decoded message. If the wire format is invalid, it throws an `Error`.
129
166
130
167
```js
131
168
try {
@@ -143,22 +180,22 @@ Note that **Message** below refers to any message type. See the next section for
143
180
works like `Message.decode` but additionally reads the length of the message prepended as a varint.
quickly creates a new runtime message from known to be valid properties without any conversion being performed. Where applicable, it is recommended to prefer `Message.create` over `Message.fromObject`.
183
+
creates a new **runtime message** from a set of properties that satisfy the requirements of a valid message. Where applicable, it is recommended to prefer `Message.create` over `Message.fromObject` because it doesn't perform possibly redundant conversion.
147
184
148
185
```js
149
186
var message =AwesomeMessage.create({ awesomeField:"AwesomeString" });
converts any plain object to a runtime message. Tries to convert whatever is specified (use `Message.verify` before if necessary).
190
+
naively converts any non-valid **plain JavaScript object** to a **runtime message**. See the table above for the exact conversion operations performed.
154
191
155
192
```js
156
193
var message =AwesomeMessage.fromObject({ awesomeField:42 });
converts a **runtime message** to an arbitrary **plain JavaScript object** for interoperability with other libraries or storage. The resulting plain JavaScript object *might* still satisfy the requirements of a valid message depending on the actual conversion options specified, but most of the time it does not.
162
199
163
200
```js
164
201
var object =AwesomeMessage.toObject(message, {
@@ -172,37 +209,10 @@ Note that **Message** below refers to any message type. See the next section for
172
209
});
173
210
```
174
211
175
-
See also: [ConversionOptions](http://dcode.io/protobuf.js/global.html#ConversionOptions)
176
-
177
-
In pictures:
212
+
For reference, the following diagram aims to display the relationships between the different methods above and the concept of a valid message:
A valid message is an object not missing any required fields and exclusively using JS types for its fields / properties that are understood by the wire format writer.
184
-
185
-
* Calling `Message.verify` with any object returns `null` if the object can be encoded as-is and otherwise the error as a string.
186
-
* Calling `Message.create` or `Message.encode` must be called with a valid message.
187
-
* Calling `Message.fromObject` with any object naively converts all values to the optimal JS type.
188
-
189
-
| Field type | Expected JS type (create, encode) | Naive conversion (fromObject)
| s-/u-/int32<br />s-/fixed32 | `Number` (32 bit integer) | `value | 0` if signed<br /> `value >>> 0` if unsigned
192
-
| s-/u-/int64<br />s-/fixed64 | `Long`-like (optimal)<br />`Number` (53 bit integer) | `Long.fromValue(value)` with long.js<br />`parseInt(value, 10)` otherwise
193
-
| float<br />double | `Number` | `Number(value)`
194
-
| bool | `Boolean` | `Boolean(value)`
195
-
| string | `String` | `String(value)`
196
-
| bytes | `Uint8Array` (optimal)<br />`Buffer` (optimal under node)<br />`Array.<Number>` (8 bit integers)<br />`String` (base64) | `base64.decode(value)` if a String<br />`Object` with non-zero `.length` is kept
197
-
| enum | `Number` (32 bit integer) | Looks up the numeric id if a string
* Explicit `undefined` and `null` are considered as not set when optional.
201
-
* Repeated fields are `Array.<T>`.
202
-
* Map fields are `Object.<string,T>` with the key being the string representation of the respective value or an 8 characters long binary hash string for `Long`-likes.
203
-
*`String` refers to both objects and values while `Number` refers to values only.
204
-
* Types marked as *optimal* provide the best performance because no conversion step (i.e. number to low and high bits or base64 string to buffer) is required.
0 commit comments