[ https://issues.apache.org/jira/browse/THRIFT-1976?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Jens Geyer updated THRIFT-1976: ------------------------------- Description: The Javascript compiler is unable to serialize maps where a struct is a key due to particularities with how Javascript treats {} objects. Using the following thrift definition: {code} struct Foo { 1: required string name; } struct Bar { 1: required string description; } struct Mapper { 1: required map<Foo,Bar> fooToBar; } {code} It produces the following javascript code: {code} Mapper.prototype.write = function(output) { output.writeStructBegin('Mapper'); if (this.fooToBar !== null && this.fooToBar !== undefined) { output.writeFieldBegin('fooToBar', Thrift.Type.MAP, 1); output.writeMapBegin(Thrift.Type.STRUCT, Thrift.Type.STRUCT, Thrift.objectLength(this.fooToBar)); // XXX // This will always fail as kiter8 will always be a String // XXX for (var kiter8 in this.fooToBar) { if (this.fooToBar.hasOwnProperty(kiter8)) { var viter9 = this.fooToBar[kiter8]; // kiter8 is a string, not an object. kiter8.write(output); viter9.write(output); } } output.writeMapEnd(); output.writeFieldEnd(); } output.writeFieldStop(); output.writeStructEnd(); return; }; {code} This code always fails since enumeration of an object's keys will always yield String values. I've annotated the relevant parts in the above code. There isn't really a simple fix for this either: Using for-in, there is no way to get a reference to the original key object. Practically, a Map type would have to be added to the thrift library with basic put()/get()/delete() operations to allow for struct maps. was: The Javascript compiler is unable to serialize maps where a struct is a key due to particularities with how Javascript treats {} objects. Using the following thrift definition: struct Foo { 1: required string name; } struct Bar { 1: required string description; } struct Mapper { 1: required map<Foo,Bar> fooToBar; } /* End */ It produces the following javascript code: /* Start -Snipped */ Mapper.prototype.write = function(output) { output.writeStructBegin('Mapper'); if (this.fooToBar !== null && this.fooToBar !== undefined) { output.writeFieldBegin('fooToBar', Thrift.Type.MAP, 1); output.writeMapBegin(Thrift.Type.STRUCT, Thrift.Type.STRUCT, Thrift.objectLength(this.fooToBar)); // XXX // This will always fail as kiter8 will always be a String // XXX for (var kiter8 in this.fooToBar) { if (this.fooToBar.hasOwnProperty(kiter8)) { var viter9 = this.fooToBar[kiter8]; // kiter8 is a string, not an object. kiter8.write(output); viter9.write(output); } } output.writeMapEnd(); output.writeFieldEnd(); } output.writeFieldStop(); output.writeStructEnd(); return; }; /* END */ This code always fails since enumeration of an object's keys will always yield String values. I've annotated the relevant parts in the above code. There isn't really a simple fix for this either: Using for-in, there is no way to get a reference to the original key object. Practically, a Map type would have to be added to the thrift library with basic put()/get()/delete() operations to allow for struct maps. > Javascript client unable to serialize/deserialize maps with struct keys > ----------------------------------------------------------------------- > > Key: THRIFT-1976 > URL: https://issues.apache.org/jira/browse/THRIFT-1976 > Project: Thrift > Issue Type: Bug > Components: JavaScript - Compiler, JavaScript - Library > Affects Versions: 0.9 > Environment: All > Reporter: Andrew Stanton > Assignee: Randy Abernethy > > The Javascript compiler is unable to serialize maps where a struct is a key > due to particularities with how Javascript treats {} objects. > Using the following thrift definition: > {code} > struct Foo { > 1: required string name; > } > struct Bar { > 1: required string description; > } > struct Mapper { > 1: required map<Foo,Bar> fooToBar; > } > {code} > It produces the following javascript code: > {code} > Mapper.prototype.write = function(output) { > output.writeStructBegin('Mapper'); > if (this.fooToBar !== null && this.fooToBar !== undefined) { > output.writeFieldBegin('fooToBar', Thrift.Type.MAP, 1); > output.writeMapBegin(Thrift.Type.STRUCT, Thrift.Type.STRUCT, > Thrift.objectLength(this.fooToBar)); > // XXX > // This will always fail as kiter8 will always be a String > // XXX > for (var kiter8 in this.fooToBar) > { > if (this.fooToBar.hasOwnProperty(kiter8)) > { > var viter9 = this.fooToBar[kiter8]; > // kiter8 is a string, not an object. > kiter8.write(output); > viter9.write(output); > } > } > output.writeMapEnd(); > output.writeFieldEnd(); > } > output.writeFieldStop(); > output.writeStructEnd(); > return; > }; > {code} > This code always fails since enumeration of an object's keys will always > yield String values. I've annotated the relevant parts in the above code. > There isn't really a simple fix for this either: Using for-in, there is no > way to get a reference to the original key object. Practically, a Map type > would have to be added to the thrift library with basic put()/get()/delete() > operations to allow for struct maps. -- This message was sent by Atlassian JIRA (v6.3.4#6332)