From 04f70976ac1cb43d178dd5878ee858519a452421 Mon Sep 17 00:00:00 2001 From: Jens Geyer Date: Mon, 17 Dec 2012 22:41:21 +0100 Subject: [PATCH] THRIFT-1768 unions can't have required fields (Compiler) Patch: Jens Geyer --- compiler/cpp/src/parse/t_struct.h | 38 +++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/compiler/cpp/src/parse/t_struct.h b/compiler/cpp/src/parse/t_struct.h index b82933dd6..ffe2af380 100644 --- a/compiler/cpp/src/parse/t_struct.h +++ b/compiler/cpp/src/parse/t_struct.h @@ -44,24 +44,59 @@ class t_struct : public t_type { t_type(program), is_xception_(false), is_union_(false), + members_validated(false), + members_with_value(0), xsd_all_(false) {} t_struct(t_program* program, const std::string& name) : t_type(program, name), is_xception_(false), is_union_(false), + members_validated(false), + members_with_value(0), xsd_all_(false) {} void set_name(const std::string& name) { name_ = name; + validate_union_members(); } void set_xception(bool is_xception) { is_xception_ = is_xception; } + void validate_union_member( t_field * field) { + if( is_union_ && (! name_.empty())) { + + // unions can't have required fields + if( field->get_req() == t_field::T_REQUIRED) { + pwarning( 1, "Required field %s of union %s set to optional.\n", field->get_name().c_str(), name_.c_str()); + field->set_req( t_field::T_OPTIONAL); + } + + // unions may have up to one member defaulted, but not more + if( field->get_value() != NULL) { + if( 1 < ++members_with_value) { + throw "Error: Field "+field->get_name()+" provides another default value for union "+name_; + } + } + } + + } + + void validate_union_members() { + if( is_union_ && (! name_.empty()) && (!members_validated)) { + members_type::const_iterator m_iter; + for (m_iter = members_in_id_order_.begin(); m_iter != members_in_id_order_.end(); ++m_iter) { + validate_union_member( *m_iter); + } + members_validated = true; + } + } + void set_union(bool is_union) { is_union_ = is_union; + validate_union_members(); } void set_xsd_all(bool xsd_all) { @@ -83,6 +118,7 @@ class t_struct : public t_type { return false; } members_in_id_order_.insert(bounds.second, elem); + validate_union_member( elem); return true; } @@ -141,6 +177,8 @@ class t_struct : public t_type { members_type members_in_id_order_; bool is_xception_; bool is_union_; + bool members_validated; + int members_with_value; bool xsd_all_; };