From cbb261bb92c6b8e156bdcf690ee77ee00bd0adf9 Mon Sep 17 00:00:00 2001 From: JackLivio Date: Fri, 3 Aug 2018 15:01:42 -0400 Subject: Add support for struct param history --- .../include/smart_objects/object_schema_item.h | 4 +- .../smart_objects/src/object_schema_item.cc | 46 ++++++-- tools/InterfaceGenerator/generator/Model.py | 31 +++--- .../generator/generators/SmartFactoryBase.py | 118 ++++++++++++++++++--- .../generator/parsers/RPCBase.py | 42 +++++++- 5 files changed, 202 insertions(+), 39 deletions(-) diff --git a/src/components/smart_objects/include/smart_objects/object_schema_item.h b/src/components/smart_objects/include/smart_objects/object_schema_item.h index df5a34a25a..8ff51d302a 100644 --- a/src/components/smart_objects/include/smart_objects/object_schema_item.h +++ b/src/components/smart_objects/include/smart_objects/object_schema_item.h @@ -71,7 +71,8 @@ class CObjectSchemaItem : public ISchemaItem { const std::string& Since = "", const std::string& Until = "", const bool IsDeprecated = false, - const bool IsRemoved = false); + const bool IsRemoved = false, + const std::vector& history_vector = {}); /** * @brief Checks the version a parameter was removed (until) * If the mobile's msg version is greater than or @@ -90,6 +91,7 @@ class CObjectSchemaItem : public ISchemaItem { boost::optional mUntil; bool mIsDeprecated; bool mIsRemoved; + std::vector mHistoryVector; }; typedef std::map Members; diff --git a/src/components/smart_objects/src/object_schema_item.cc b/src/components/smart_objects/src/object_schema_item.cc index bab952411b..c17a2221db 100644 --- a/src/components/smart_objects/src/object_schema_item.cc +++ b/src/components/smart_objects/src/object_schema_item.cc @@ -54,7 +54,8 @@ CObjectSchemaItem::SMember::SMember(const ISchemaItemPtr SchemaItem, const std::string& Since, const std::string& Until, const bool IsDeprecated, - const bool IsRemoved) + const bool IsRemoved, + const std::vector& history_vector) : mSchemaItem(SchemaItem), mIsMandatory(IsMandatory) { if (Since.size() > 0) { @@ -83,6 +84,7 @@ CObjectSchemaItem::SMember::SMember(const ISchemaItemPtr SchemaItem, mIsDeprecated = IsDeprecated; mIsRemoved = IsRemoved; + mHistoryVector = history_vector; } @@ -107,7 +109,6 @@ bool CObjectSchemaItem::SMember::CheckHistoryFieldVersion(const utils::SemanticV } } - printf("Final true of check history version\n"); return true; //Not enough version information. Default true. } @@ -176,10 +177,33 @@ Errors::eType CObjectSchemaItem::validate(const SmartObject& object, ++it) { const std::string& key = it->first; const SMember& member = it->second; - printf("key: %s\n", key.c_str()); std::set::const_iterator key_it = object_keys.find(key); if (object_keys.end() == key_it) { - if (member.mIsMandatory && member.CheckHistoryFieldVersion(MessageVersion)) { + if(member.mSince.is_initialized() && MessageVersion < member.mSince.get() && member.mHistoryVector.size() > 0) { + //Message version predates parameter and a history vector exists. + for (uint i=0; i= member.mHistoryVector[i].mSince.get()) { + if (member.mHistoryVector[i].mUntil.is_initialized() && MessageVersion >= member.mHistoryVector[i].mUntil.get()) { + //MessageVersion is newer than the specified "Until" version + continue; + } else { + if (member.mHistoryVector[i].mIsMandatory == true && (member.mHistoryVector[i].mIsRemoved == false)) { + std::string validation_info = "Missing mandatory parameter since and until: " + key; + report__->set_validation_info(validation_info); + return Errors::MISSING_MANDATORY_PARAMETER; + } + break; + } + } else if (member.mHistoryVector[i].mSince.is_initialized() == false && member.mHistoryVector[i].mUntil.is_initialized() && MessageVersion < member.mHistoryVector[i].mUntil.get()){ + if (member.mHistoryVector[i].mIsMandatory == true && (member.mHistoryVector[i].mIsRemoved == false)) { + std::string validation_info = "Missing mandatory parameter until: " + key; + report__->set_validation_info(validation_info); + return Errors::MISSING_MANDATORY_PARAMETER; + } + break; + } + } + } else if (member.mIsMandatory && member.CheckHistoryFieldVersion(MessageVersion) && (member.mIsMandatory == false)) { std::string validation_info = "Missing mandatory parameter: " + key; report__->set_validation_info(validation_info); return Errors::MISSING_MANDATORY_PARAMETER; @@ -286,8 +310,18 @@ void CObjectSchemaItem::RemoveFakeParams(SmartObject& Object, const utils::Seman } else if (members_it->second.mIsRemoved && members_it->second.CheckHistoryFieldVersion(MessageVersion)) { ++it; Object.erase(key); - } else { - it++; + } else if (members_it->second.mHistoryVector.size() > 0) { + for (uint i=0; isecond.mHistoryVector.size(); i++) { + if (members_it->second.mHistoryVector[i].CheckHistoryFieldVersion(MessageVersion) && members_it->second.mHistoryVector[i].mIsRemoved) { + ++it; + Object.erase(key); + break; + } + } + ++it; + } + else { + ++it; } } } diff --git a/tools/InterfaceGenerator/generator/Model.py b/tools/InterfaceGenerator/generator/Model.py index c4d2eca0bd..827553bda2 100755 --- a/tools/InterfaceGenerator/generator/Model.py +++ b/tools/InterfaceGenerator/generator/Model.py @@ -125,7 +125,7 @@ class InterfaceItemBase(object): def __init__(self, name, description=None, design_description=None, issues=None, todos=None, platform=None, default_value=None, scope=None, - since=None, until=None, deprecated=None, removed=None): + since=None, until=None, deprecated=None, removed=None, history=None): self.name = name self.description = description if description is not None else [] self.design_description = \ @@ -139,6 +139,7 @@ class InterfaceItemBase(object): self.until = until self.deprecated = deprecated self.removed = removed + self.history = history class EnumElement(InterfaceItemBase): @@ -154,11 +155,11 @@ class EnumElement(InterfaceItemBase): def __init__(self, name, description=None, design_description=None, issues=None, todos=None, platform=None, internal_name=None, - value=None, since=None, until=None, deprecated=None, removed=None): + value=None, since=None, until=None, deprecated=None, removed=None, history=None): super(EnumElement, self).__init__( name, description=description, design_description=design_description, issues=issues, todos=todos, - platform=platform) + platform=platform, history=history) self.internal_name = internal_name self.value = value self.since = since @@ -190,11 +191,11 @@ class Enum(InterfaceItemBase): def __init__(self, name, description=None, design_description=None, issues=None, todos=None, platform=None, internal_scope=None, - elements=None, scope=None, since=None, until=None, deprecated=None, removed=None): + elements=None, scope=None, since=None, until=None, deprecated=None, removed=None, history=None): super(Enum, self).__init__( name, description=description, design_description=design_description, issues=issues, todos=todos, - platform=platform, scope=scope) + platform=platform, scope=scope, history=history) self.internal_scope = internal_scope self.elements = \ @@ -218,11 +219,11 @@ class EnumSubset(InterfaceItemBase): def __init__(self, name, enum, description=None, design_description=None, issues=None, todos=None, platform=None, - allowed_elements=None, since=None, until=None, deprecated=None, removed=None): + allowed_elements=None, since=None, until=None, deprecated=None, removed=None, history=None): super(EnumSubset, self).__init__( name, description=description, design_description=design_description, issues=issues, todos=todos, - platform=platform) + platform=platform, history=history) self.enum = enum self.allowed_elements = \ @@ -248,11 +249,11 @@ class Param(InterfaceItemBase): def __init__(self, name, param_type, description=None, design_description=None, issues=None, todos=None, platform=None, is_mandatory=True, default_value=None, scope=None, - since=None, until=None, deprecated=None, removed=None): + since=None, until=None, deprecated=None, removed=None, history=None): super(Param, self).__init__( name, description=description, design_description=design_description, issues=issues, todos=todos, - platform=platform, default_value=default_value, scope=scope) + platform=platform, default_value=default_value, scope=scope, history=history) self.is_mandatory = is_mandatory self.param_type = param_type @@ -275,12 +276,12 @@ class FunctionParam(Param): def __init__(self, name, param_type, description=None, design_description=None, issues=None, todos=None, platform=None, is_mandatory=True, default_value=None, scope=None, - since=None, until=None, deprecated=None, removed=None): + since=None, until=None, deprecated=None, removed=None, history=None): super(FunctionParam, self).__init__( name, param_type=param_type, description=description, design_description=design_description, issues=issues, todos=todos, platform=platform, is_mandatory=is_mandatory, default_value=default_value, - scope=scope, since=since, until=until, deprecated=deprecated, removed=removed) + scope=scope, since=since, until=until, deprecated=deprecated, removed=removed, history=history) self.default_value = default_value @@ -296,12 +297,12 @@ class Struct(InterfaceItemBase): def __init__(self, name, description=None, design_description=None, issues=None, todos=None, platform=None, members=None, scope=None, - since=None, until=None, deprecated=None, removed=None): + since=None, until=None, deprecated=None, removed=None, history=None): super(Struct, self).__init__( name, description=description, design_description=design_description, issues=issues, todos=todos, platform=platform, scope=scope, since=since, until=until, - deprecated=deprecated, removed=removed) + deprecated=deprecated, removed=removed, history=history) print since self.members = \ @@ -321,11 +322,11 @@ class Function(InterfaceItemBase): def __init__(self, name, function_id, message_type, description=None, design_description=None, issues=None, todos=None, - platform=None, params=None, scope=None, since=None, until=None, deprecated=None, removed=None): + platform=None, params=None, scope=None, since=None, until=None, deprecated=None, removed=None, history=None): super(Function, self).__init__( name, description=description, design_description=design_description, issues=issues, todos=todos, - platform=platform, scope=scope, since=None, until=None, deprecated=None, removed=None) + platform=platform, scope=scope, since=since, until=until, deprecated=deprecated, removed=removed, history=history) self.function_id = function_id self.message_type = message_type diff --git a/tools/InterfaceGenerator/generator/generators/SmartFactoryBase.py b/tools/InterfaceGenerator/generator/generators/SmartFactoryBase.py index 05dd939ad0..65359fe54e 100755 --- a/tools/InterfaceGenerator/generator/generators/SmartFactoryBase.py +++ b/tools/InterfaceGenerator/generator/generators/SmartFactoryBase.py @@ -600,10 +600,43 @@ class CodeGenerator(object): """ - result = u"\n\n".join( - [self._gen_schema_item_decl(x) for x in members]) + result_array = [] + for x in members: + result_array.append(self._gen_schema_item_decl(x)) + count = 0 + if x.history is not None: + history_list = x.history + for item in history_list: + item.name += "_history_v" + str(len(history_list)-count) + result_array.append(self._gen_schema_item_decl(item)) + count += 1 + result_array.append(self._gen_history_vector_decl(history_list, x.name)) + + result = u"\n\n".join(result_array) + return result + + def _gen_history_vector_decl(self, history_list, name): + """Generate History Vector Declaration. + + Generates the declaration and initialization + of a vector of schema items + + Arguments: + history_list -> list of history items + name -> name of parent parameter name + + Returns: + String with history array code. + """ + result_array = [] + result_array.append(self._impl_code_shared_ptr_vector_template.substitute(var_name = name)) + '''for item in history_list: + result_array.append(self._impl_code_append_history_vector_template.substitute(vector_name=name, item_name=item.name)) +''' + result = u"\n".join(result_array) + return result + - return u"".join([result, u"\n\n"]) if result else u"" def _gen_schema_item_decl(self, member): """Generate schema item declaration. @@ -759,10 +792,16 @@ class CodeGenerator(object): String with function schema items fill code. """ - - result = u"\n".join( - [self._gen_schema_item_fill(x, since, until, deprecated, removed) for x in members]) - + result_array = [] + for x in members: + #If history, create Smember History vector first + if x.history is not None: + history_list = x.history + for item in history_list: + result_array.append(self._gen_history_vector_item_fill(item, x.name)) + result_array.append(self._gen_schema_item_fill(x, since, until, deprecated, removed)) + + result = u"\n".join(result_array) return u"".join([result, u"\n\n"]) if result else u"" def _gen_schema_params_fill(self, message_type_name): @@ -804,20 +843,59 @@ class CodeGenerator(object): member.until is not None or member.deprecated is not None or member.removed is not None): - return self._impl_code_item_fill_template_with_version.substitute( - name=member.name, - var_name=self._gen_schema_item_var_name(member), - is_mandatory=u"true" if member.is_mandatory is True else u"false", - since=member.since if member.since is not None else since if since is not None else "", - until=member.until if member.until is not None else until if until is not None else "", - deprecated=member.deprecated if member.deprecated is not None else deprecated if deprecated is not None else u"false", - removed=member.removed if member.removed is not None else removed if removed is not None else u"false") + if member.history is not None: + return self._impl_code_item_fill_template_with_version_and_history_vector.substitute( + name=member.name, + var_name=self._gen_schema_item_var_name(member), + is_mandatory=u"true" if member.is_mandatory is True else u"false", + since=member.since if member.since is not None else since if since is not None else "", + until=member.until if member.until is not None else until if until is not None else "", + deprecated=member.deprecated if member.deprecated is not None else deprecated if deprecated is not None else u"false", + removed=member.removed if member.removed is not None else removed if removed is not None else u"false", + vector_name=member.name) + else: + return self._impl_code_item_fill_template_with_version.substitute( + name=member.name, + var_name=self._gen_schema_item_var_name(member), + is_mandatory=u"true" if member.is_mandatory is True else u"false", + since=member.since if member.since is not None else since if since is not None else "", + until=member.until if member.until is not None else until if until is not None else "", + deprecated=member.deprecated if member.deprecated is not None else deprecated if deprecated is not None else u"false", + removed=member.removed if member.removed is not None else removed if removed is not None else u"false") else: return self._impl_code_item_fill_template.substitute( name=member.name, var_name=self._gen_schema_item_var_name(member), is_mandatory=u"true" if member.is_mandatory is True else u"false") + def _gen_history_vector_item_fill(self, member, vector_name): + """Generate schema item fill code. + + Generates source code that fills history vector with item. + + Keyword arguments: + member -- struct member/function parameter to process. + + Returns: + String with schema item fill code. + + """ + + if (member.since is not None or + member.until is not None or + member.deprecated is not None or + member.removed is not None): + return self._impl_code_append_history_vector_template.substitute( + vector_name=vector_name, + name=member.name, + mandatory=u"true" if member.is_mandatory is True else u"false", + since=member.since if member.since is not None else "", + until=member.until if member.until is not None else "", + deprecated=member.deprecated if member.deprecated is not None else u"false", + removed=member.removed if member.removed is not None else u"false") + else: + print "Warning! History item does not have any version history. Omitting %s" % member.name + @staticmethod def _gen_schema_item_var_name(member): """Generate schema item variable name. @@ -1524,6 +1602,12 @@ class CodeGenerator(object): u'''${comment}''' u'''std::shared_ptr ${var_name} = ${item_decl};''') + _impl_code_shared_ptr_vector_template = string.Template( + u'''std::vector ${var_name}_history_vector;''') + + _impl_code_append_history_vector_template = string.Template( + u'''${vector_name}_history_vector.push_back(CObjectSchemaItem::SMember(${name}_SchemaItem, ${mandatory}, "${since}", "${until}", ${deprecated}, ${removed}));''') + _impl_code_integer_item_template = string.Template( u'''TNumberSchemaItem<${type}>::create(${params})''') @@ -1554,6 +1638,10 @@ class CodeGenerator(object): u'''schema_members["${name}"] = CObjectSchemaItem::''' u'''SMember(${var_name}, ${is_mandatory}, "${since}", "${until}", ${deprecated}, ${removed});''') + _impl_code_item_fill_template_with_version_and_history_vector = string.Template( + u'''schema_members["${name}"] = CObjectSchemaItem::''' + u'''SMember(${var_name}, ${is_mandatory}, "${since}", "${until}", ${deprecated}, ${removed}, ${vector_name}_history_vector);''') + _function_impl_template = string.Template( u'''CSmartSchema $namespace::$class_name::''' u'''InitFunction_${function_id}_${message_type}(\n''' diff --git a/tools/InterfaceGenerator/generator/parsers/RPCBase.py b/tools/InterfaceGenerator/generator/parsers/RPCBase.py index d3e103ce7a..c587a97b3a 100755 --- a/tools/InterfaceGenerator/generator/parsers/RPCBase.py +++ b/tools/InterfaceGenerator/generator/parsers/RPCBase.py @@ -416,6 +416,8 @@ class Parser(object): issues = [] todos = [] subelements = [] + history = None + warnings = [] if "name" not in element.attrib: raise ParseError("Name is not specified for " + element.tag) @@ -436,6 +438,12 @@ class Parser(object): todos.append(self._parse_simple_element(subelement)) elif subelement.tag == "issue": issues.append(self._parse_issue(subelement)) + elif subelement.tag == "history": + if history is not None: + raise ParseError("Elements can only have one history tag: " + element.tag) + history = self._parse_history(subelement, prefix, element) + elif subelement.tag == "warning": + warnings.append(self._parse_warning(subelement)) else: subelements.append(subelement) @@ -443,6 +451,7 @@ class Parser(object): params["design_description"] = design_description params["issues"] = issues params["todos"] = todos + params["history"] = history return params, subelements, attrib @@ -640,8 +649,6 @@ class Parser(object): removed = self._extract_attrib(attrib, "removed") if removed is not None: params["removed"] = removed - print("FOUND REMOVED!!!!!") - print(params["name"]) is_mandatory = self._extract_attrib(attrib, "mandatory") @@ -880,3 +887,34 @@ class Parser(object): version_array.append("0") dot_str = "." return dot_str.join(version_array) + + def _parse_history(self, history, prefix, parent): + print "Pare History of Size: %d" % len(history) + if history.tag != "history": + raise ParseError("Invalid history tag: " + interface.tag) + + items = [] + + for subelement in history: + if subelement.tag == "enum" and parent.tag == "enum": + items.append(self._parse_enum(subelement, prefix)) + elif subelement.tag == "element" and parent.tag == "element": + items.append(self._parse_enum_element(subelement)) + elif subelement.tag == "description" and parent.tag == "description": + items.append(self._parse_simple_element(subelement)) + elif subelement.tag == "struct" and parent.tag == "struct": + items.append(self._parse_struct(subelement, prefix)) + elif subelement.tag == "param" and parent.tag == "param": + items.append(self._parse_function_param(subelement, prefix)) + elif subelement.tag == "function" and parent.tag == "function": + items.append(self.__parse_function(subelement, prefix)) + else: + print subelement.tag + print parent.tag + raise ParseError("A history tag must be nested within the element it notes the history for. Fix item: '" + + parent.attrib["name"] + "'") + + return items + def _parse_warning(self, warning): + print "Parse warning" + -- cgit v1.2.1