Commit d13e734b authored by Peng Huang's avatar Peng Huang Committed by Commit Bot

mojo: Support deserialize mojom struct from binary data in JS

This CL adds --js_deserializable_struct=gpu.mojom.VulkanInfo param
for mojom binding generator to allow generating  js deserialize
method for specified mojom struct.

Bug: 887018
Change-Id: I98f2224e7422d52fb0c4aeb684078dd191f8e616
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1869685Reviewed-by: default avatarKen Rockot <rockot@google.com>
Commit-Queue: Peng Huang <penghuang@chromium.org>
Cr-Commit-Position: refs/heads/master@{#710098}
parent f63636c2
...@@ -274,6 +274,15 @@ action_foreach("validation_test_data_list") { ...@@ -274,6 +274,15 @@ action_foreach("validation_test_data_list") {
] ]
} }
mojom("test_deserializer_interface") {
testonly = true
generate_java = true
sources = [
"deserializer.test-mojom",
]
js_generate_struct_deserializers = true
}
mojom("test_interfaces") { mojom("test_interfaces") {
testonly = true testonly = true
generate_java = true generate_java = true
...@@ -300,6 +309,7 @@ mojom("test_interfaces") { ...@@ -300,6 +309,7 @@ mojom("test_interfaces") {
] ]
public_deps = [ public_deps = [
":echo", ":echo",
":test_deserializer_interface",
":test_mojom_import", ":test_mojom_import",
":test_mojom_import2", ":test_mojom_import2",
"//mojo/public/mojom/base", "//mojo/public/mojom/base",
......
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
module deserializer;
struct TestStruct {
int32 v1;
int32 v2;
int64 v3;
};
...@@ -1330,6 +1330,22 @@ mojo.internal.Struct = function(objectToBlessAsType, name, packedSize, fields) { ...@@ -1330,6 +1330,22 @@ mojo.internal.Struct = function(objectToBlessAsType, name, packedSize, fields) {
}; };
}; };
/**
* @param {!mojo.internal.MojomType} structMojomType
* @return {!Function}
* @export
*/
mojo.internal.createStructDeserializer = function(structMojomType) {
return function(dataView) {
if (structMojomType.$ == undefined ||
structMojomType.$.structSpec == undefined) {
throw new Error("Invalid struct mojom type!");
}
const decoder = new mojo.internal.Decoder(dataView, []);
return decoder.decodeStructInline(structMojomType.$.structSpec);
};
};
/** /**
* @param {!Object} objectToBlessAsUnion * @param {!Object} objectToBlessAsUnion
* @param {string} name * @param {string} name
......
...@@ -33,6 +33,11 @@ mojo.internal.Struct( ...@@ -33,6 +33,11 @@ mojo.internal.Struct(
{%- endfor %} {%- endfor %}
]); ]);
{% if generate_struct_deserializers %}
{{module.namespace}}.{{struct.name}}_Deserialize =
mojo.internal.createStructDeserializer({{module.namespace}}.{{struct.name}}Spec.$);
{% endif %}
{% if generate_closure_exports -%} {% if generate_closure_exports -%}
goog.provide('{{module.namespace}}.{{struct.name}}'); goog.provide('{{module.namespace}}.{{struct.name}}');
......
...@@ -264,6 +264,7 @@ class Generator(generator.Generator): ...@@ -264,6 +264,7 @@ class Generator(generator.Generator):
"unions": self.module.unions, "unions": self.module.unions,
"generate_fuzzing": self.generate_fuzzing, "generate_fuzzing": self.generate_fuzzing,
"generate_closure_exports": for_compile, "generate_closure_exports": for_compile,
"generate_struct_deserializers": self.js_generate_struct_deserializers,
} }
@staticmethod @staticmethod
......
...@@ -294,6 +294,9 @@ if (enable_mojom_typemapping) { ...@@ -294,6 +294,9 @@ if (enable_mojom_typemapping) {
# use_typescript_sources (optional) # use_typescript_sources (optional)
# Uses the Typescript generator to generate JavaScript bindings. # Uses the Typescript generator to generate JavaScript bindings.
# #
# js_generate_struct_deserializers (optiona)
# Generates JS deerialize methods for structs.
#
# The following parameters are used to support the component build. They are # The following parameters are used to support the component build. They are
# needed so that bindings which are linked with a component can use the same # needed so that bindings which are linked with a component can use the same
# export settings for classes. The first three are for the chromium variant, and # export settings for classes. The first three are for the chromium variant, and
...@@ -1283,6 +1286,11 @@ template("mojom") { ...@@ -1283,6 +1286,11 @@ template("mojom") {
"--js_bindings_mode=new", "--js_bindings_mode=new",
] ]
if (defined(invoker.js_generate_struct_deserializers) &&
invoker.js_generate_struct_deserializers) {
args += [ "--js_generate_struct_deserializers" ]
}
if (!defined(invoker.scramble_message_ids) || if (!defined(invoker.scramble_message_ids) ||
invoker.scramble_message_ids) { invoker.scramble_message_ids) {
inputs += message_scrambling_inputs inputs += message_scrambling_inputs
......
...@@ -219,6 +219,8 @@ class MojomProcessor(object): ...@@ -219,6 +219,8 @@ class MojomProcessor(object):
variant=args.variant, bytecode_path=args.bytecode_path, variant=args.variant, bytecode_path=args.bytecode_path,
for_blink=args.for_blink, for_blink=args.for_blink,
js_bindings_mode=args.js_bindings_mode, js_bindings_mode=args.js_bindings_mode,
js_generate_struct_deserializers=\
args.js_generate_struct_deserializers,
export_attribute=args.export_attribute, export_attribute=args.export_attribute,
export_header=args.export_header, export_header=args.export_header,
generate_non_variant_code=args.generate_non_variant_code, generate_non_variant_code=args.generate_non_variant_code,
...@@ -470,6 +472,10 @@ def main(): ...@@ -470,6 +472,10 @@ def main():
help="This option only affects the JavaScript bindings. The value could " help="This option only affects the JavaScript bindings. The value could "
"be \"new\" to generate new-style lite JS bindings in addition to the " "be \"new\" to generate new-style lite JS bindings in addition to the "
"old, or \"old\" to only generate old bindings.") "old, or \"old\" to only generate old bindings.")
generate_parser.add_argument(
"--js_generate_struct_deserializers", action="store_true",
help="Generate javascript deserialize methods for structs in "
"mojom-lite.js file")
generate_parser.add_argument( generate_parser.add_argument(
"--export_attribute", default="", "--export_attribute", default="",
help="Optional attribute to specify on class declaration to export it " help="Optional attribute to specify on class declaration to export it "
......
...@@ -194,6 +194,7 @@ class Generator(object): ...@@ -194,6 +194,7 @@ class Generator(object):
def __init__(self, module, output_dir=None, typemap=None, variant=None, def __init__(self, module, output_dir=None, typemap=None, variant=None,
bytecode_path=None, for_blink=False, bytecode_path=None, for_blink=False,
js_bindings_mode="new", js_bindings_mode="new",
js_generate_struct_deserializers=False,
export_attribute=None, export_attribute=None,
export_header=None, generate_non_variant_code=False, export_header=None, generate_non_variant_code=False,
support_lazy_serialization=False, disallow_native_types=False, support_lazy_serialization=False, disallow_native_types=False,
...@@ -206,6 +207,7 @@ class Generator(object): ...@@ -206,6 +207,7 @@ class Generator(object):
self.bytecode_path = bytecode_path self.bytecode_path = bytecode_path
self.for_blink = for_blink self.for_blink = for_blink
self.js_bindings_mode = js_bindings_mode self.js_bindings_mode = js_bindings_mode
self.js_generate_struct_deserializers = js_generate_struct_deserializers
self.export_attribute = export_attribute self.export_attribute = export_attribute
self.export_header = export_header self.export_header = export_header
self.generate_non_variant_code = generate_non_variant_code self.generate_non_variant_code = generate_non_variant_code
......
<!DOCTYPE html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/gen/layout_test_data/mojo/public/js/mojo_bindings_lite.js"></script>
<script src="/gen/mojo/public/interfaces/bindings/tests/deserializer.test-mojom-lite.js"></script>
<script>
'use strict';
test(() => {
const data = new Uint32Array([
0, 0, // header
8899, // v1
9988, // v2
7777, 0 // v3
]);
const dataview = new DataView(data.buffer);
const s = deserializer.TestStruct_Deserialize(dataview);
assert_equals(s.v1, 8899);
assert_equals(s.v2, 9988);
assert_equals(s.v3, 7777);
}, 'deserializer');
</script>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment