You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@thrift.apache.org by "Jens Geyer (JIRA)" <ji...@apache.org> on 2014/11/25 22:14:13 UTC

[jira] [Updated] (THRIFT-1976) Javascript client unable to serialize/deserialize maps with struct keys

     [ 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)