• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1{#  TODO(yzshen): Make these templates more readable. #}
2
3{#  Serializes the specified struct.
4    |struct| is the struct definition.
5    |struct_display_name| is the display name for the struct that can be showed
6    in error/log messages, for example, "FooStruct", "FooMethod request".
7    |input_field_pattern| should be a pattern that contains one string
8    placeholder, for example, "input->%s", "p_%s". The placeholder will be
9    substituted with struct field names to refer to the input fields.
10    |writer| is the name of the BufferWriter to use for allocation and writing.
11    |buffer| is the name of the Buffer instance used.
12    |context| is the name of the serialization context.
13    |input_may_be_temp|: please see the comments of get_serialized_size.
14    This macro is expanded to do serialization for both:
15    - user-defined structs: the input is an instance of the corresponding struct
16      wrapper class.
17    - method parameters/response parameters: the input is a list of
18      arguments. #}
19{%- macro serialize(struct, struct_display_name, input_field_pattern, writer,
20                    buffer, context, input_may_be_temp=False) -%}
21  {{writer}}.Allocate({{buffer}});
22{%- for pf in struct.packed.packed_fields_in_ordinal_order %}
23{%-   set input_field = input_field_pattern|format(pf.field.name) %}
24{%-   set name = pf.field.name %}
25{%-   set kind = pf.field.kind %}
26{%-   set serializer_type = kind|unmapped_type_for_serializer %}
27
28{%-   if kind|is_object_kind or kind|is_any_handle_or_interface_kind %}
29{%-     set original_input_field = input_field_pattern|format(name) %}
30{%-     set input_field = "in_%s"|format(name) if input_may_be_temp
31                                               else original_input_field %}
32{%-     if input_may_be_temp %}
33  decltype({{original_input_field}}) in_{{name}} = {{original_input_field}};
34{%-     endif %}
35{%-   endif %}
36
37{%-   if kind|is_object_kind %}
38{%-     if kind|is_array_kind or kind|is_map_kind %}
39  typename decltype({{writer}}->{{name}})::BaseType::BufferWriter
40      {{name}}_writer;
41  const mojo::internal::ContainerValidateParams {{name}}_validate_params(
42      {{kind|get_container_validate_params_ctor_args|indent(10)}});
43  mojo::internal::Serialize<{{serializer_type}}>(
44      {{input_field}}, {{buffer}}, &{{name}}_writer, &{{name}}_validate_params,
45      {{context}});
46  {{writer}}->{{name}}.Set(
47      {{name}}_writer.is_null() ? nullptr : {{name}}_writer.data());
48{%-     elif kind|is_union_kind %}
49  typename decltype({{writer}}->{{name}})::BufferWriter {{name}}_writer;
50  {{name}}_writer.AllocateInline({{buffer}}, &{{writer}}->{{name}});
51  mojo::internal::Serialize<{{serializer_type}}>(
52      {{input_field}}, {{buffer}}, &{{name}}_writer, true, {{context}});
53{%-     else %}
54  typename decltype({{writer}}->{{name}})::BaseType::BufferWriter
55      {{name}}_writer;
56  mojo::internal::Serialize<{{serializer_type}}>(
57      {{input_field}}, {{buffer}}, &{{name}}_writer, {{context}});
58  {{writer}}->{{name}}.Set(
59      {{name}}_writer.is_null() ? nullptr : {{name}}_writer.data());
60{%-     endif %}
61{%-     if not kind|is_nullable_kind %}
62  MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
63      {{writer}}->{{name}}.is_null(),
64      mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
65      "null {{name}} in {{struct_display_name}}");
66{%-     endif %}
67
68{%-   elif kind|is_any_handle_or_interface_kind %}
69  mojo::internal::Serialize<{{serializer_type}}>(
70      {{input_field}}, &{{writer}}->{{name}}, {{context}});
71{%-     if not kind|is_nullable_kind %}
72  MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
73      !mojo::internal::IsHandleOrInterfaceValid({{writer}}->{{name}}),
74{%-       if kind|is_associated_kind %}
75      mojo::internal::VALIDATION_ERROR_UNEXPECTED_INVALID_INTERFACE_ID,
76{%-       else %}
77      mojo::internal::VALIDATION_ERROR_UNEXPECTED_INVALID_HANDLE,
78{%-       endif %}
79      "invalid {{name}} in {{struct_display_name}}");
80{%-     endif %}
81
82{%-   elif kind|is_enum_kind %}
83  mojo::internal::Serialize<{{serializer_type}}>(
84      {{input_field}}, &{{writer}}->{{name}});
85
86{%-   else %}
87  {{writer}}->{{name}} = {{input_field}};
88{%-   endif %}
89{%- endfor %}
90{%- endmacro -%}
91
92{#  Deserializes the specified struct.
93    |struct| is the struct definition.
94    |input| is the name of the input struct data view. It is expected to be
95    non-null.
96    |output_field_pattern| should be a pattern that contains one string
97    placeholder, for example, "result->%s", "p_%s". The placeholder will be
98    substituted with struct field names to refer to the output fields.
99    |context| is the name of the serialization context.
100    |success| is the name of a bool variable to track success of the operation.
101    This macro is expanded to do deserialization for both:
102    - user-defined structs: the output is an instance of the corresponding
103      struct wrapper class.
104    - method parameters/response parameters: the output is a list of
105      arguments. #}
106{%- macro deserialize(struct, input, output_field_pattern, success) -%}
107{%-   for pf in struct.packed.packed_fields_in_ordinal_order %}
108{%-     set output_field = output_field_pattern|format(pf.field.name) %}
109{%-     set name = pf.field.name %}
110{%-     set kind = pf.field.kind %}
111{%-     if kind|is_object_kind or kind|is_enum_kind %}
112  if (!{{input}}.Read{{name|under_to_camel}}(&{{output_field}}))
113    {{success}} = false;
114{%-     elif kind|is_any_handle_kind %}
115  {{output_field}} = {{input}}.Take{{name|under_to_camel}}();
116{%-     elif kind|is_any_interface_kind %}
117  {{output_field}} =
118      {{input}}.Take{{name|under_to_camel}}<decltype({{output_field}})>();
119{%-     else %}
120  {{output_field}} = {{input}}.{{name}}();
121{%-     endif %}
122{%-   endfor %}
123{%- endmacro %}
124