Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Which JS types are valid in fromObject, create, and encode? #719

Closed
seishun opened this issue Mar 23, 2017 · 10 comments
Closed

Which JS types are valid in fromObject, create, and encode? #719

seishun opened this issue Mar 23, 2017 · 10 comments
Labels

Comments

@seishun
Copy link
Contributor

seishun commented Mar 23, 2017

For instance, in which cases am I allowed to specify enum values as strings rather than numbers?

syntax = "proto3";

message DeviceReadings {
  enum Foo {
    ONE = 0;
    TWO = 1;
  } 

  Foo foo = 1;
}

When I use a string in encode it seems to fall back to the default value:

> DeviceReadings.decode(DeviceReadings.encode({foo: 'TWO'}).finish())
DeviceReadings { foo: 0 }

But if I go through fromObject first then it works:

> DeviceReadings.decode(DeviceReadings.encode(DeviceReadings.fromObject({foo: 'TWO'})).finish())
DeviceReadings { foo: 1 }

But with create it works the same as encode alone:

> DeviceReadings.decode(DeviceReadings.encode(DeviceReadings.create({foo: 'TWO'})).finish())
DeviceReadings { foo: 0 }

Is all that documented somewhere?

@dcodeIO
Copy link
Member

dcodeIO commented Mar 23, 2017

There is a new Usage section in the README that tries to explain the differences. Basically, .create and .encode expect a valid object, while .fromObject performs conversion to proper internal types and .verify can be used to test if an object would encode properly.

@seishun
Copy link
Contributor Author

seishun commented Mar 23, 2017

That's great, but it would be even greater if it also described what is considered "valid" and what kind of conversions fromObject can do.

@dcodeIO
Copy link
Member

dcodeIO commented Mar 23, 2017

Using this issue to create some documentation to copy to the README eventually. Let me know if I am missing something!


What is a valid message?

A valid message is an object not missing any required fields and exclusively using JS types for its fields that are understood by the wire format writer.

  • Calling Message.verify with a valid message returns null and otherwise the error as a string.
  • Calling Message.create or Message.encode with any object assumes valid types.
  • Calling Message.fromObject with any object naively converts all values to the optimal JS type.
Type Expected JS type (create) Naive conversion (fromObject)
int32
uint32
sint32
fixed32
sfixed32
Number (32 bit integer) `value
int64
uint64
sint64
fixed64
sfixed64
Long-like (optimal)
Number (53 bit integer)
Long.fromValue(value)
parseInt(value, 10) without long.js
float
double
Number Number(value)
bool Boolean Boolean(value)
string String String(value)
bytes Uint8Array (optimal)
Buffer (optimal)
Array.<Number> (8 bit integers)
String (base64)
base64.decode(value) if a String
Object with non-zero .length is kept
enum Number (32 bit integer) Looks up the numeric id if a string
message Valid message Message.fromObject(value)
  • Explicit undefined and null are considered as not set when optional.
  • Repeated fields are Array.<T>.
  • 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.
  • String refers to both objects and values.

@dcodeIO
Copy link
Member

dcodeIO commented Mar 23, 2017

Is this approximately what you have been looking for?

@seishun
Copy link
Contributor Author

seishun commented Mar 23, 2017

Looks good, but it doesn't mention that enum can be a string in the "naive conversion".

I think it should also be mentioned which conversion is performed by encode.

Also IMO if you list Buffer objects as Buffer, then people might think that String means a String object (rather than a string value).

@dcodeIO
Copy link
Member

dcodeIO commented Mar 23, 2017

Added enums in the meantime. String is both String objects and string values.

@seishun
Copy link
Contributor Author

seishun commented Mar 23, 2017

Looks great, thank you!

@seishun
Copy link
Contributor Author

seishun commented Mar 23, 2017

Another thing. According to my experiments, if there's a oneof field, you must set the virtual property to the name of the set field, otherwise it's not serialized. If that's correct, then that should also be mentioned.

@dcodeIO
Copy link
Member

dcodeIO commented Mar 23, 2017

This has changed lately to encode whatever is present.

Related: #710

@dcodeIO
Copy link
Member

dcodeIO commented Apr 11, 2017

Closing this issue for now as it hasn't received any replies recently. Feel free to reopen it if necessary!

@dcodeIO dcodeIO closed this as completed Apr 11, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants