Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(344)

Side by Side Diff: mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl

Issue 1387993002: mojo::Serialize*_() calls now propogate/return validation errors. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: unscope VALIDATION_ERROR_* enum values. early exit on null-input. additional comments Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 {# TODO(yzshen): Make these templates more readable. #} 1 {# TODO(yzshen): Make these templates more readable. #}
2 2
3 {# Computes the serialized size for the specified struct. 3 {# Computes the serialized size for the specified struct.
4 |struct| is the struct definition. 4 |struct| is the struct definition.
5 |input_field_pattern| should be a pattern that contains one string 5 |input_field_pattern| should be a pattern that contains one string
6 placeholder, for example, "input->%s", "p_%s". The placeholder will be 6 placeholder, for example, "input->%s", "p_%s". The placeholder will be
7 substituted with struct field names to refer to the input fields. 7 substituted with struct field names to refer to the input fields.
8 This macro is expanded to compute seriailized size for both: 8 This macro is expanded to compute seriailized size for both:
9 - user-defined structs: the input is an instance of the corresponding struct 9 - user-defined structs: the input is an instance of the corresponding struct
10 wrapper class. 10 wrapper class.
11 - method parameters/response parameters: the input is a list of 11 - method parameters/response parameters: the input is a list of
12 arguments. 12 arguments.
13 It declares |size| of type size_t to store the resulting size. #} 13 It declares |size| of type size_t to store the resulting size. #}
14 {%- macro get_serialized_size(struct, input_field_pattern) -%} 14 {%- macro get_serialized_size(struct, input_field_pattern) -%}
15 size_t size = sizeof(internal::{{struct.name}}_Data); 15 size_t size = sizeof(internal::{{struct.name}}_Data);
16 {%- for pf in struct.packed.packed_fields_in_ordinal_order if pf.field.kind|is _object_kind %} 16 {%- for pf in struct.packed.packed_fields_in_ordinal_order if pf.field.kind|is _object_kind %}
17 {%- if pf.field.kind|is_union_kind %} 17 {%- if pf.field.kind|is_union_kind %}
18 size += GetSerializedSize_({{input_field_pattern|format(pf.field.name)}}, true ); 18 size += GetSerializedSize_({{input_field_pattern|format(pf.field.name)}}, true );
19 {%- elif pf.field.kind|is_struct_kind %} 19 {%- elif pf.field.kind|is_struct_kind %}
20 size += {{input_field_pattern|format(pf.field.name)}}.is_null() 20 size += {{input_field_pattern|format(pf.field.name)}}.is_null()
21 ? 0 21 ? 0
22 : GetSerializedSize_(*{{input_field_pattern|format(pf.field.name)} }); 22 : GetSerializedSize_(*{{input_field_pattern|format(pf.field.name)} });
23 {%- else %} 23 {%- else %}
24 size += GetSerializedSize_({{input_field_pattern|format(pf.field.name)}}); 24 size += GetSerializedSize_({{input_field_pattern|format(pf.field.name)}});
25 {%- endif %} 25 {%- endif %}
26 {%- endfor %} 26 {%- endfor %}
27 {%- endmacro -%} 27 {%- endmacro -%}
28 28
29 {# A private macro that prints the C++ log-and-report serialization errors
30 macro, and conditionally returns if |should_return_errors| #}
31 {%- macro _validation_check_macro(condition, error_code, error_msg, should_retur n_errors=false) -%}
32 if ({{condition}}) {
33 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING({{error_code}}, "{{error_msg}}");
34 {%- if should_return_errors %}
35 return {{error_code}};
36 {%- endif %}
37 }
38 {%- endmacro -%}
39
40 {# The following 4 macros call |SerializeArray_|, |SerializeMap_|,
41 |SerializeUnion_| and |Serialize_| respectively. If |should_return_error|
42 is true, these macros do the extra work of propagating non-successful error
43 codes. #}
44 {%- macro call_serialize_array(name, kind, input, buffer, output,
45 should_return_errors, indent_size) -%}
46 {
47 const mojo::internal::ArrayValidateParams {{name}}_validate_params(
48 {{kind|get_array_validate_params_ctor_args|indent(indent_size)}});
49 {%- if should_return_errors -%}
50 auto retval =
51 {%- endif -%}
52 mojo::SerializeArray_({{input}}, {{buffer}}, {{output}},
53 &{{name}}_validate_params);
54 {%- if should_return_errors %}
55 if (retval != mojo::internal::VALIDATION_ERROR_NONE)
56 return retval;
57 {%- endif %}
58 }
59 {%- endmacro -%}
60
61 {%- macro call_serialize_map(name, kind, input, buffer, output,
62 should_return_errors, indent_size) -%}
63 {
64 const mojo::internal::ArrayValidateParams {{name}}_validate_params(
65 {{kind.value_kind|get_map_validate_params_ctor_args|indent(indent_size)} });
66 {%- if should_return_errors -%}
67 auto retval =
68 {%- endif -%}
69 mojo::SerializeMap_(
70 {{input}}, {{buffer}}, {{output}},
71 &{{name}}_validate_params);
72 {%- if should_return_errors %}
73 if (retval != mojo::internal::VALIDATION_ERROR_NONE)
74 return retval;
75 {%- endif %}
76 }
77 {%- endmacro -%}
78
79 {%- macro call_serialize_union(input, buffer, output, inlined,
80 should_return_errors) -%}
81 {
82 {%- if should_return_errors -%}
83 auto retval =
84 {%- endif -%}
85 SerializeUnion_({{input}},
86 {{buffer}},
87 {{output}},
88 {{inlined}});
89 {%- if should_return_errors %}
90 if (retval != mojo::internal::VALIDATION_ERROR_NONE)
91 return retval;
92 {%- endif %}
93 }
94 {%- endmacro -%}
95
96 {%- macro call_serialize_struct(input, buffer, output, should_return_errors) -%}
97 {
98 {%- if should_return_errors -%}
99 auto retval =
100 {%- endif -%}
101 Serialize_({{input}},
102 {{buffer}},
103 {{output}});
104 {%- if should_return_errors %}
105 if (retval != mojo::internal::VALIDATION_ERROR_NONE)
106 return retval;
107 {%- endif %}
108 }
109 {%- endmacro -%}
110
29 {# Serializes the specified struct. 111 {# Serializes the specified struct.
30 |struct| is the struct definition. 112 |struct| is the struct definition.
31 |struct_display_name| is the display name for the struct that can be showed 113 |struct_display_name| is the display name for the struct that can be showed
32 in error/log messages, for example, "FooStruct", "FooMethod request". 114 in error/log messages, for example, "FooStruct", "FooMethod request".
33 |input_field_pattern| should be a pattern that contains one string 115 |input_field_pattern| should be a pattern that contains one string
34 placeholder, for example, "input->%s", "p_%s". The placeholder will be 116 placeholder, for example, "input->%s", "p_%s". The placeholder will be
35 substituted with struct field names to refer to the input fields. 117 substituted with struct field names to refer to the input fields.
36 |output| is the name of the output struct instance. 118 |output| is the name of the output struct instance.
37 |buffer| is the name of the Buffer instance used. 119 |buffer| is the name of the Buffer instance used.
120 |should_return_errors| is true if validation errors need to be return'd.
121 This is needed when serializing interface parameters, where you cannot
122 return.
123
38 This macro is expanded to do serialization for both: 124 This macro is expanded to do serialization for both:
39 - user-defined structs: the input is an instance of the corresponding struct 125 - user-defined structs: the input is an instance of the corresponding struct
40 wrapper class. 126 wrapper class.
41 - method parameters/response parameters: the input is a list of 127 - method parameters/response parameters: the input is a list of
42 arguments. #} 128 arguments.
43 {%- macro serialize(struct, struct_display_name, input_field_pattern, output, bu ffer) -%} 129 This macro is expanded within the C++ struct serialization methods #}
130 {%- macro serialize(struct, struct_display_name, input_field_pattern,
131 output, buffer, should_return_errors=false) -%}
44 internal::{{struct.name}}_Data* {{output}} = 132 internal::{{struct.name}}_Data* {{output}} =
45 internal::{{struct.name}}_Data::New({{buffer}}); 133 internal::{{struct.name}}_Data::New({{buffer}});
46 {%- for pf in struct.packed.packed_fields_in_ordinal_order %} 134 {%- for pf in struct.packed.packed_fields_in_ordinal_order %}
47 {%- set input_field = input_field_pattern|format(pf.field.name) %} 135 {%- set input_field = input_field_pattern|format(pf.field.name) %}
48 {%- set name = pf.field.name %} 136 {%- set name = pf.field.name %}
49 {%- set kind = pf.field.kind %} 137 {%- set kind = pf.field.kind %}
50 {%- if kind|is_object_kind %} 138 {%- if kind|is_object_kind %}
51 {%- if kind|is_array_kind %} 139 {%- if kind|is_array_kind %}
52 const mojo::internal::ArrayValidateParams {{name}}_validate_params( 140 {{call_serialize_array(name = name,
53 {{kind|get_array_validate_params_ctor_args|indent(10)}}); 141 kind = kind,
54 mojo::SerializeArray_(&{{input_field}}, {{buffer}}, 142 input = '&' ~ input_field,
55 &{{output}}->{{name}}.ptr, &{{name}}_validate_params); 143 buffer = buffer,
144 output = "&%s->%s.ptr"|format(output,name),
145 should_return_errors = should_return_errors,
146 indent_size = 10)}}
56 {%- elif kind|is_map_kind %} 147 {%- elif kind|is_map_kind %}
57 const mojo::internal::ArrayValidateParams {{name}}_validate_params( 148 {{call_serialize_map(name = name,
58 {{kind.value_kind|get_map_validate_params_ctor_args|indent(10)}}); 149 kind = kind,
59 mojo::SerializeMap_( 150 input = '&' ~ input_field,
60 &{{input_field}}, {{buffer}}, &{{output}}->{{name}}.ptr, 151 buffer = buffer,
61 &{{name}}_validate_params); 152 output = '&%s->%s.ptr'|format(output,name),
153 should_return_errors = should_return_errors,
154 indent_size = 10)}}
62 {%- elif kind|is_union_kind %} 155 {%- elif kind|is_union_kind %}
63 internal::{{kind.name}}_Data* {{name}}_ptr = &{{output}}->{{name}}; 156 internal::{{kind.name}}_Data* {{name}}_ptr = &{{output}}->{{name}};
64 SerializeUnion_({{input_field}}.get(), {{buffer}}, &{{name}}_ptr, true); 157 {{call_serialize_union(input = input_field ~ ".get()",
158 buffer = buffer,
159 output = "&%s_ptr"|format(name),
160 inlined = "true",
161 should_return_errors = should_return_errors)}}
65 {%- elif kind|is_string_kind %} 162 {%- elif kind|is_string_kind %}
66 SerializeString_({{input_field}}, {{buffer}}, &{{output}}->{{name}}.ptr); 163 SerializeString_({{input_field}}, {{buffer}}, &{{output}}->{{name}}.ptr);
67 {%- else %} 164 {%- else %}
68 Serialize_({{input_field}}.get(), {{buffer}}, &{{output}}->{{name}}.ptr); 165 {{call_serialize_struct(input = input_field ~ ".get()",
166 buffer = buffer,
167 output = "&%s->%s.ptr"|format(output,name),
168 should_return_errors = should_return_errors)}}
69 {%- endif %} 169 {%- endif %}
70 {%- if not kind|is_nullable_kind %} 170 {%- if not kind|is_nullable_kind %}
71 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
72 {%- if kind|is_union_kind %} 171 {%- if kind|is_union_kind %}
73 {{output}}->{{name}}.is_null(), 172 {%- set condition = "%s->%s.is_null()" | format(output, name) %}
74 {%- else %} 173 {%- else %}
75 !{{output}}->{{name}}.ptr, 174 {%- set condition = "!%s->%s.ptr" | format(output,name) %}
76 {%- endif %} 175 {%- endif %}
77 mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER, 176 {{_validation_check_macro(
78 "null {{name}} in {{struct_display_name}}"); 177 condition = condition,
178 error_code = "mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER",
179 error_msg = "null %s in %s" | format(name, struct_display_name),
180 should_return_errors = should_return_errors)}}
79 {%- endif %} 181 {%- endif %}
80 {%- elif kind|is_any_handle_kind or kind|is_interface_kind %} 182 {%- elif kind|is_any_handle_kind or kind|is_interface_kind %}
81 {%- if kind|is_interface_kind %} 183 {%- if kind|is_interface_kind %}
82 mojo::internal::InterfacePointerToData({{input_field}}.Pass(), &{{output}}->{{ name}}); 184 mojo::internal::InterfacePointerToData({{input_field}}.Pass(), &{{output}}->{{ name}});
83 {%- elif kind|is_interface_request_kind %} 185 {%- elif kind|is_interface_request_kind %}
84 {{output}}->{{name}} = {{input_field}}.PassMessagePipe().release(); 186 {{output}}->{{name}} = {{input_field}}.PassMessagePipe().release();
85 {%- else %} 187 {%- else %}
86 {{output}}->{{name}} = {{input_field}}.release(); 188 {{output}}->{{name}} = {{input_field}}.release();
87 {%- endif %} 189 {%- endif %}
88 {%- if not kind|is_nullable_kind %} 190 {%- if not kind|is_nullable_kind %}
89 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
90 {%- if kind|is_interface_kind %} 191 {%- if kind|is_interface_kind %}
91 !{{output}}->{{name}}.handle.is_valid(), 192 {%- set condition = "!%s->%s.handle.is_valid()" | format(output, name) % }
92 {%- else %} 193 {%- else %}
93 !{{output}}->{{name}}.is_valid(), 194 {%- set condition = "!%s->%s.is_valid()" | format(output,name) %}
94 {%- endif %} 195 {%- endif %}
95 mojo::internal::VALIDATION_ERROR_UNEXPECTED_INVALID_HANDLE, 196 {{_validation_check_macro(
96 "invalid {{name}} in {{struct_display_name}}"); 197 condition = condition,
198 error_code = "mojo::internal::VALIDATION_ERROR_UNEXPECTED_INVALID_HANDLE",
199 error_msg = "invalid %s in %s" | format(name, struct_display_name),
200 should_return_errors = should_return_errors)}}
97 {%- endif %} 201 {%- endif %}
98 {%- elif kind|is_enum_kind %} 202 {%- elif kind|is_enum_kind %}
99 {{output}}->{{name}} = 203 {{output}}->{{name}} =
100 static_cast<int32_t>({{input_field}}); 204 static_cast<int32_t>({{input_field}});
101 {%- else %} 205 {%- else %}
102 {{output}}->{{name}} = {{input_field}}; 206 {{output}}->{{name}} = {{input_field}};
103 {%- endif %} 207 {%- endif %}
104 {%- endfor %} 208 {%- endfor %}
105 {%- endmacro -%} 209 {%- endmacro -%}
106 210
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
153 {%- elif kind|is_any_handle_kind %} 257 {%- elif kind|is_any_handle_kind %}
154 {{output_field}}.reset(mojo::internal::FetchAndReset(&{{input}}->{{name}})); 258 {{output_field}}.reset(mojo::internal::FetchAndReset(&{{input}}->{{name}}));
155 {%- elif kind|is_enum_kind %} 259 {%- elif kind|is_enum_kind %}
156 {{output_field}} = static_cast<{{kind|cpp_wrapper_type}}>({{input}}->{{name} }); 260 {{output_field}} = static_cast<{{kind|cpp_wrapper_type}}>({{input}}->{{name} });
157 {%- else %} 261 {%- else %}
158 {{output_field}} = {{input}}->{{name}}; 262 {{output_field}} = {{input}}->{{name}};
159 {%- endif %} 263 {%- endif %}
160 {%- endfor %} 264 {%- endfor %}
161 } while (false); 265 } while (false);
162 {%- endmacro %} 266 {%- endmacro %}
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698