Skip to content

Commit dd9662a

Browse files
hchokshimeta-codesync[bot]
authored andcommitted
Create Whisker equivalents for remaining cpp_mstch_struct properties
Summary: Migrate `struct:explicitly_constructed_fields` to a Whisker property on the `t_structured` prototye. Also add `fields_in_layout_order` to the `t_structured` Whisker prototype, with the mstch property retained due to templates using mstch implicit `first?` / `last?`. Reviewed By: iahs Differential Revision: D96202278 fbshipit-source-id: 943ab386350b29b07cb2330125a0c436392bd0a3
1 parent 5dc1540 commit dd9662a

7 files changed

Lines changed: 100 additions & 58 deletions

File tree

third-party/thrift/src/thrift/compiler/generate/t_mstch_cpp2_generator.cc

Lines changed: 54 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,42 @@ struct cpp2_field_generator_context {
388388
std::vector<const t_field*> get_structured_fields_in_layout_order(
389389
const t_structured& strct);
390390

391+
/**
392+
* Check fields for the meeting any of the following criteria:
393+
* All enums
394+
* All primitives except empty strings
395+
* All non-empty structs and containers
396+
* All non-optional references with basetypes, enums, non-empty structs, and
397+
* containers
398+
*/
399+
bool is_field_explicitly_constructed(
400+
const t_field& field, const t_structured& parent_struct) {
401+
const t_type* type = field.type()->get_true_type();
402+
if (cpp2::is_explicit_ref(&field) &&
403+
field.qualifier() == t_field_qualifier::optional) {
404+
return false;
405+
}
406+
if (type->is<t_enum>()) {
407+
return true;
408+
}
409+
if (type->is<t_primitive_type>()) {
410+
return !type->is_string_or_binary() || field.default_value() != nullptr ||
411+
cpp2::is_explicit_ref(&field);
412+
}
413+
if (type->is<t_struct>() || type->is<t_union>()) {
414+
return type != &parent_struct &&
415+
(cpp2::is_explicit_ref(&field) ||
416+
(field.default_value() != nullptr &&
417+
!field.default_value()->is_empty()));
418+
}
419+
if (type->is<t_container>()) {
420+
return cpp2::is_explicit_ref(&field) ||
421+
(field.default_value() != nullptr &&
422+
!field.default_value()->is_empty());
423+
}
424+
return false;
425+
}
426+
391427
class cpp2_generator_context {
392428
public:
393429
explicit cpp2_generator_context(
@@ -1315,6 +1351,21 @@ class t_mstch_cpp2_generator : public t_mstch_generator {
13151351
}
13161352
return whisker::make::array(std::move(fields));
13171353
});
1354+
def.property("fields_in_layout_order", [&](const t_structured& strct) {
1355+
return to_array(
1356+
cpp_context_->fields_in_layout_order(strct), proto.of<t_field>());
1357+
});
1358+
def.property(
1359+
"explicitly_constructed_fields", [&](const t_structured& strct) {
1360+
std::vector<const t_field*> filtered;
1361+
for (const t_field* field :
1362+
cpp_context_->fields_in_layout_order(strct)) {
1363+
if (is_field_explicitly_constructed(*field, strct)) {
1364+
filtered.emplace_back(field);
1365+
}
1366+
}
1367+
return to_array(filtered, proto.of<t_field>());
1368+
});
13181369

13191370
return std::move(def).make();
13201371
}
@@ -2102,8 +2153,6 @@ class cpp_mstch_struct : public mstch_struct {
21022153
register_methods(
21032154
this,
21042155
{
2105-
{"struct:explicitly_constructed_fields",
2106-
&cpp_mstch_struct::explicitly_constructed_fields},
21072156
{"struct:fields_in_layout_order",
21082157
&cpp_mstch_struct::fields_in_layout_order},
21092158
});
@@ -2112,42 +2161,10 @@ class cpp_mstch_struct : public mstch_struct {
21122161
private:
21132162
const cpp2_generator_context& cpp_context_;
21142163

2115-
mstch::node explicitly_constructed_fields() {
2116-
// Filter fields according to the following criteria:
2117-
// Get all enums
2118-
// Get all base_types but empty strings
2119-
// Get all non-empty structs and containers
2120-
// Get all non-optional references with basetypes, enums,
2121-
// non-empty structs, and containers
2122-
std::vector<const t_field*> filtered_fields;
2123-
for (const auto* field : cpp_context_.fields_in_layout_order(*struct_)) {
2124-
const t_type* type = field->type()->get_true_type();
2125-
// Filter out all optional references.
2126-
if (cpp2::is_explicit_ref(field) &&
2127-
field->qualifier() == t_field_qualifier::optional) {
2128-
continue;
2129-
}
2130-
if (type->is<t_enum>() ||
2131-
(type->is<t_primitive_type>() && !type->is_string_or_binary()) ||
2132-
(type->is_string_or_binary() && field->default_value() != nullptr) ||
2133-
(type->is<t_container>() && field->default_value() != nullptr &&
2134-
!field->default_value()->is_empty()) ||
2135-
((type->is<t_struct>() || type->is<t_union>()) &&
2136-
(struct_ != type->try_as<t_struct>()) &&
2137-
((field->default_value() && !field->default_value()->is_empty()) ||
2138-
(cpp2::is_explicit_ref(field) &&
2139-
field->qualifier() != t_field_qualifier::optional))) ||
2140-
(type->is<t_container>() && cpp2::is_explicit_ref(field) &&
2141-
field->qualifier() != t_field_qualifier::optional) ||
2142-
(type->is<t_primitive_type>() && cpp2::is_explicit_ref(field) &&
2143-
field->qualifier() != t_field_qualifier::optional)) {
2144-
filtered_fields.push_back(field);
2145-
}
2146-
}
2147-
return make_mstch_fields(filtered_fields);
2148-
}
2149-
21502164
mstch::node fields_in_layout_order() {
2165+
// TODO(T256504524): An equivalent Whisker property has been created, but we
2166+
// first need to migrate templates that rely on mstch behavior like implicit
2167+
// `first?`/`last?` properties
21512168
return make_mstch_fields(cpp_context_.fields_in_layout_order(*struct_));
21522169
}
21532170
};
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
{{!
2+
3+
Copyright (c) Meta Platforms, Inc. and affiliates.
4+
5+
Licensed under the Apache License, Version 2.0 (the "License");
6+
you may not use this file except in compliance with the License.
7+
You may obtain a copy of the License at
8+
9+
http://www.apache.org/licenses/LICENSE-2.0
10+
11+
Unless required by applicable law or agreed to in writing, software
12+
distributed under the License is distributed on an "AS IS" BASIS,
13+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
See the License for the specific language governing permissions and
15+
limitations under the License.
16+
17+
}}
18+
19+
{{! Note: All adapted fields need to use field tag. }}
20+
{{#let export partial tag |field struct|}}
21+
{{#pragma ignore-newlines}}
22+
{{#if field.cpp_adapter}}
23+
::apache::thrift::op::get_field_tag<{{struct.cpp_underlying_name}}, ::apache::thrift::field_id<{{field.id}}>>
24+
{{#else}}
25+
{{field.type_tag}}
26+
{{/if field.cpp_adapter}}
27+
{{/let partial}}

third-party/thrift/src/thrift/compiler/generate/templates/cpp2/field/tag.mustache

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1414
See the License for the specific language governing permissions and
1515
limitations under the License.
16-
17-
// Note: All adapted fields need to use field tag.
18-
}}{{^field:cpp_adapter}}{{field:type_tag}}{{/field:cpp_adapter}}{{!
19-
}}{{#field:cpp_adapter}}::apache::thrift::op::get_field_tag<{{struct:cpp_underlying_name}}, ::apache::thrift::field_id<{{field:id}}>>{{/field:cpp_adapter}}
16+
}}
17+
{{#pragma ignore-newlines}}
18+
{{#partial fields.tag field=field:self struct=struct:self}}

third-party/thrift/src/thrift/compiler/generate/templates/cpp2/module_types.cpp.mustache

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
1717
}}
1818
{{#import "common/const_value" as const_value}}
19+
{{#import "common/fields" as fields}}
1920
{{> Autogen}}
2021
#include "{{program:include_prefix}}{{program:name}}_types.tcc"
2122
#include "{{program:include_prefix}}{{program:name}}_constants.h"

third-party/thrift/src/thrift/compiler/generate/templates/cpp2/module_types.h.mustache

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
1717
}}
1818
{{#import "common/const_value" as const_value}}
19+
{{#import "common/fields" as fields}}
1920
{{#import "types/schema_association" as schema_association}}
2021
{{> Autogen}}
2122

third-party/thrift/src/thrift/compiler/generate/templates/cpp2/module_types_custom_protocol.h.mustache

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
1717
}}
1818
{{#import "common/const_value" as const_value}}
19+
{{#import "common/fields" as fields}}
1920
{{> Autogen}}
2021
#pragma once
2122

third-party/thrift/src/thrift/compiler/generate/templates/cpp2/module_types_h/base_ctor_no_alloc_init_list.mustache

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -14,20 +14,16 @@
1414
See the License for the specific language governing permissions and
1515
limitations under the License.
1616
17-
18-
}}{{! --------------- Empty constractor, no allocator, init list
19-
}}{{struct:cpp_underlying_name}}(){{!
20-
}}{{#struct:explicitly_constructed_fields}}{{> common/colon_newline}}{{!
21-
}}{{#field:type}}{{!
22-
}} {{field:cpp_storage_name}}({{!
23-
}}{{#field:cpp_ref_not_boxed?}}{{> module_types_h/smart_ptr_constructor}}{{/field:cpp_ref_not_boxed?}}{{!
24-
}}{{#field:boxed_ref?}}{{> field/default}}{{/field:boxed_ref?}}{{!
25-
TODO(dokwon): Support custom default for intern boxed field.
26-
}}{{#field:intern_boxed_ref?}}{{field:cpp_storage_type}}::fromStaticConstant(&::apache::thrift::op::getDefault<{{> field/tag}}>()){{/field:intern_boxed_ref?}}{{!
27-
}}{{^field:cpp_ref?}}{{#field:default_value}}{{!
28-
Use value initialization when no custom default is provided.
29-
}}{{> field/default}}{{/field:default_value}}{{!
30-
}}{{/field:cpp_ref?}}{{!
31-
}}){{> common/comma_newline}}{{!
32-
}}{{/field:type}}{{!
33-
}}{{/struct:explicitly_constructed_fields}}{{!}}
17+
}}{{! Empty constructor, no allocator, init list !}}
18+
{{#pragma ignore-newlines}}
19+
{{struct:cpp_underlying_name}}()
20+
{{#each (array.enumerate struct:explicitly_constructed_fields with_first=true with_last=true) as |i field first? last?|}}
21+
{{> common/colon_newline}} {{field.cpp_storage_name}}(
22+
{{#if field.cpp_ref_not_boxed?}}{{#field}}{{#field.type}}{{> module_types_h/smart_ptr_constructor}}{{/field.type}}{{/field}}{{/if}}
23+
{{#if field.boxed_ref?}}{{#field}}{{#field.type}}{{> field/default}}{{/field.type}}{{/field}}{{/if}}
24+
{{! TODO(dokwon): Support custom default for intern boxed field. }}
25+
{{#if field.intern_boxed_ref?}}{{field.cpp_storage_type}}::fromStaticConstant(&::apache::thrift::op::getDefault<{{#partial fields.tag field=field struct=struct:self}}>()){{/if}}
26+
{{! Use value initialization when no custom default is provided. }}
27+
{{#if (not field.cpp_ref?)}}{{#field}}{{#field.type}}{{#field.default_value}}{{> field/default}}{{/field.default_value}}{{/field.type}}{{/field}}{{/if}}
28+
){{> common/comma_newline}}
29+
{{/each}}

0 commit comments

Comments
 (0)