| {%- 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 %} |