2626extern int g_warn;
2727extern std::string g_curpath;
2828extern bool g_return_failure;
29+ extern bool g_audit_allow_optional_field_removal;
30+ extern bool g_audit_allow_required_field_to_default;
2931
3032void thrift_audit_warning (int level, const char * fmt, ...) {
3133 if (g_warn < level) {
@@ -49,6 +51,19 @@ void thrift_audit_failure(const char* fmt, ...) {
4951 g_return_failure = true ;
5052}
5153
54+ static bool is_allowed_field_removal (const t_field* oldField) {
55+ return g_audit_allow_optional_field_removal
56+ && oldField->get_req () == t_field::T_OPTIONAL ;
57+ }
58+
59+ static void report_field_removal (const t_field* oldField, const std::string& structName) {
60+ if (!is_allowed_field_removal (oldField)) {
61+ thrift_audit_failure (" Struct Field removed for Id = %d in %s \n " ,
62+ oldField->get_key (),
63+ structName.c_str ());
64+ }
65+ }
66+
5267void compare_namespace (t_program* newProgram, t_program* oldProgram)
5368{
5469 const std::map<std::string, std::string>& newNamespaceMap = newProgram->get_all_namespaces ();
@@ -226,7 +241,12 @@ void compare_struct_field(t_field* newField, t_field* oldField, std::string oldS
226241 bool newStructFieldOptional = (newField->get_req () != t_field::T_REQUIRED );
227242 bool oldStructFieldOptional = (oldField->get_req () != t_field::T_REQUIRED );
228243
229- if (newStructFieldOptional != oldStructFieldOptional)
244+ bool requiredToDefaultAllowed =
245+ g_audit_allow_required_field_to_default
246+ && oldField->get_req () == t_field::T_REQUIRED
247+ && newField->get_req () == t_field::T_OPT_IN_REQ_OUT ;
248+
249+ if (newStructFieldOptional != oldStructFieldOptional && !requiredToDefaultAllowed)
230250 {
231251 thrift_audit_failure (" Struct Field Requiredness Changed for Id = %d in %s \n " , newField->get_key (), oldStructName.c_str ());
232252 }
@@ -261,7 +281,7 @@ void compare_single_struct(t_struct* newStruct, t_struct* oldStruct, const std::
261281 if (newStructMemberIt == newStructMembersInIdOrder.end () && oldStructMemberIt != oldStructMembersInIdOrder.end ())
262282 {
263283 // A field ID has been removed from the end.
264- thrift_audit_failure ( " Struct Field removed for Id = %d in %s \n " , ( *oldStructMemberIt)-> get_key () , structName. c_str () );
284+ report_field_removal ( *oldStructMemberIt, structName);
265285 oldStructMemberIt++;
266286 }
267287 else if (newStructMemberIt != newStructMembersInIdOrder.end () && oldStructMemberIt == oldStructMembersInIdOrder.end ())
@@ -291,7 +311,7 @@ void compare_single_struct(t_struct* newStruct, t_struct* oldStruct, const std::
291311 else if ((*newStructMemberIt)->get_key () > (*oldStructMemberIt)->get_key ())
292312 {
293313 // A field is deleted in newStruct.
294- thrift_audit_failure ( " Struct Field removed for Id = %d in %s \n " , ( *oldStructMemberIt)-> get_key () , structName. c_str () );
314+ report_field_removal ( *oldStructMemberIt, structName);
295315 oldStructMemberIt++;
296316 }
297317
0 commit comments