blob: 4823febeca9f20b1ffcfe685962e12ab8f28a570 [file] [log] [blame]
{%- macro union_def(union) %}
function {{union.name}}(value) {
this.initDefault_();
this.initValue_(value);
}
{{tags(union)}}
{{union.name}}.prototype.initDefault_ = function() {
this.$data = null;
this.$tag = undefined;
}
{{union.name}}.prototype.initValue_ = function(value) {
if (value == undefined) {
return;
}
var keys = Object.keys(value);
if (keys.length == 0) {
return;
}
if (keys.length > 1) {
throw new TypeError("You may set only one member on a union.");
}
var fields = [
{%- for field in union.fields %}
"{{field.name}}",
{%- endfor %}
];
if (fields.indexOf(keys[0]) < 0) {
throw new ReferenceError(keys[0] + " is not a {{union.name}} member.");
}
this[keys[0]] = value[keys[0]];
}
{%- for field in union.fields %}
Object.defineProperty({{union.name}}.prototype, "{{field.name}}", {
get: function() {
if (this.$tag != {{union.name}}.Tags.{{field.name}}) {
throw new ReferenceError(
"{{union.name}}.{{field.name}} is not currently set.");
}
return this.$data;
},
set: function(value) {
this.$tag = {{union.name}}.Tags.{{field.name}};
this.$data = value;
}
});
{%- endfor %}
{{encode(union)|indent(2)}}
{{decode(union)|indent(2)}}
{{validate(union)|indent(2)}}
{{union.name}}.encodedSize = 16;
{%- endmacro %}
{%- macro tags(union) %}
{{union.name}}.Tags = {
{%- for field in union.fields %}
{{field.name}}: {{field.ordinal}},
{%- endfor %}
};
{%- endmacro %}
{%- macro encode(union) %}
{{union.name}}.encode = function(encoder, val) {
if (val == null) {
encoder.writeUint64(0);
encoder.writeUint64(0);
return;
}
if (val.$tag == undefined) {
throw new TypeError("Cannot encode unions with an unknown member set.");
}
encoder.writeUint32(16);
encoder.writeUint32(val.$tag);
switch (val.$tag) {
{%- for field in union.fields %}
case {{union.name}}.Tags.{{field.name}}:
{%- if field|is_bool_field %}
encoder.writeUint8(val.{{field.name}} ? 1 : 0);
{%- else %}
encoder.{{field.kind|union_encode_snippet}}val.{{field.name}});
{%- endif %}
break;
{%- endfor %}
}
encoder.align();
};
{%- endmacro %}
{%- macro decode(union) %}
{{union.name}}.decode = function(decoder) {
var size = decoder.readUint32();
if (size == 0) {
decoder.readUint32();
decoder.readUint64();
return null;
}
var result = new {{union.name}}();
var tag = decoder.readUint32();
switch (tag) {
{%- for field in union.fields %}
case {{union.name}}.Tags.{{field.name}}:
{%- if field|is_bool_field %}
result.{{field.name}} = decoder.readUint8() ? true : false;
{%- else %}
result.{{field.name}} = decoder.{{field.kind|union_decode_snippet}};
{%- endif %}
break;
{%- endfor %}
}
decoder.align();
return result;
};
{%- endmacro %}
{%- from "validation_macros.tmpl" import validate_union_field %}
{%- macro validate(union) %}
{{union.name}}.validate = function(messageValidator, offset) {
var size = messageValidator.decodeUnionSize(offset);
if (size != 16) {
return validator.validationError.INVALID_UNION_SIZE;
}
var tag = messageValidator.decodeUnionTag(offset);
var data_offset = offset + 8;
var err;
switch (tag) {
{%- for field in union.fields %}
{%- set name = union.name ~ '.' ~ field.name %}
case {{union.name}}.Tags.{{field.name}}:
{{validate_union_field(field, "data_offset", name)}}
break;
{%- endfor %}
}
return validator.validationError.NONE;
};
{%- endmacro %}