diff options
author | Mark Benvenuto <mark.benvenuto@mongodb.com> | 2017-06-29 11:53:10 -0400 |
---|---|---|
committer | Mark Benvenuto <mark.benvenuto@mongodb.com> | 2017-06-29 11:53:10 -0400 |
commit | 0966ba7c98dcd47d6fff753cf380d1c38c2c3d2b (patch) | |
tree | 548e4b3d45888789d1e0a75c9d04fc4aa7e512dc /buildscripts/idl/idl/parser.py | |
parent | 103256372fc4f4cec1c736482c1ed520ee0de290 (diff) | |
download | mongo-0966ba7c98dcd47d6fff753cf380d1c38c2c3d2b.tar.gz |
SERVER-29634 Support overriding the C++ name for chained structs/types in IDL
Diffstat (limited to 'buildscripts/idl/idl/parser.py')
-rw-r--r-- | buildscripts/idl/idl/parser.py | 114 |
1 files changed, 95 insertions, 19 deletions
diff --git a/buildscripts/idl/idl/parser.py b/buildscripts/idl/idl/parser.py index de9cbd2dc01..bfe825376df 100644 --- a/buildscripts/idl/idl/parser.py +++ b/buildscripts/idl/idl/parser.py @@ -65,9 +65,7 @@ def _generic_parser( # pylint: disable=too-many-branches field_name_set = set() # type: Set[str] - for node_pair in node.value: - first_node = node_pair[0] - second_node = node_pair[1] + for [first_node, second_node] in node.value: first_name = first_node.value @@ -129,9 +127,7 @@ def _parse_mapping( if not ctxt.is_mapping_node(node, syntax_node_name): return - for node_pair in node.value: - first_node = node_pair[0] - second_node = node_pair[1] + for [first_node, second_node] in node.value: first_name = first_node.value @@ -213,9 +209,7 @@ def _parse_fields(ctxt, node): field_name_set = set() # type: Set[str] - for node_pair in node.value: - first_node = node_pair[0] - second_node = node_pair[1] + for [first_node, second_node] in node.value: first_name = first_node.value @@ -238,6 +232,92 @@ def _parse_fields(ctxt, node): return fields +def _parse_chained_type(ctxt, name, node): + # type: (errors.ParserContext, str, yaml.nodes.MappingNode) -> syntax.ChainedType + """Parse a chained type in a struct in the IDL file.""" + chain = syntax.ChainedType(ctxt.file_name, node.start_mark.line, node.start_mark.column) + chain.name = name + + _generic_parser(ctxt, node, "chain", chain, { + "cpp_name": _RuleDesc('scalar'), + }) + + return chain + + +def _parse_chained_types(ctxt, node): + # type: (errors.ParserContext, yaml.nodes.MappingNode) -> List[syntax.ChainedType] + """Parse a chained types section in a struct in the IDL file.""" + chained_items = [] + + field_name_set = set() # type: Set[str] + + for [first_node, second_node] in node.value: + first_name = first_node.value + + if first_name in field_name_set: + ctxt.add_duplicate_error(first_node, first_name) + continue + + # Simple Scalar + if second_node.id == "scalar": + chain = syntax.ChainedType(ctxt.file_name, node.start_mark.line, node.start_mark.column) + chain.name = first_name + chain.cpp_name = second_node.value + chained_items.append(chain) + else: + chain = _parse_chained_type(ctxt, first_name, second_node) + chained_items.append(chain) + + field_name_set.add(first_name) + + return chained_items + + +def _parse_chained_struct(ctxt, name, node): + # type: (errors.ParserContext, str, yaml.nodes.MappingNode) -> syntax.ChainedStruct + """Parse a chained struct in a struct in the IDL file.""" + chain = syntax.ChainedStruct(ctxt.file_name, node.start_mark.line, node.start_mark.column) + chain.name = name + + _generic_parser(ctxt, node, "chain", chain, { + "cpp_name": _RuleDesc('scalar'), + }) + + return chain + + +def _parse_chained_structs(ctxt, node): + # type: (errors.ParserContext, yaml.nodes.MappingNode) -> List[syntax.ChainedStruct] + """Parse a chained structs in a struct in the IDL file.""" + chained_items = [] + + field_name_set = set() # type: Set[str] + + for [first_node, second_node] in node.value: + + first_name = first_node.value + + if first_name in field_name_set: + ctxt.add_duplicate_error(first_node, first_name) + continue + + # Simple Scalar + if second_node.id == "scalar": + chain = syntax.ChainedStruct(ctxt.file_name, node.start_mark.line, + node.start_mark.column) + chain.name = first_name + chain.cpp_name = second_node.value + chained_items.append(chain) + else: + chain = _parse_chained_struct(ctxt, first_name, second_node) + chained_items.append(chain) + + field_name_set.add(first_name) + + return chained_items + + def _parse_struct(ctxt, spec, name, node): # type: (errors.ParserContext, syntax.IDLSpec, unicode, Union[yaml.nodes.MappingNode, yaml.nodes.ScalarNode, yaml.nodes.SequenceNode]) -> None """Parse a struct section in the IDL file.""" @@ -250,8 +330,8 @@ def _parse_struct(ctxt, spec, name, node): _generic_parser(ctxt, node, "struct", struct, { "description": _RuleDesc('scalar', _RuleDesc.REQUIRED), "fields": _RuleDesc('mapping', mapping_parser_func=_parse_fields), - "chained_types": _RuleDesc('sequence'), - "chained_structs": _RuleDesc('sequence'), + "chained_types": _RuleDesc('mapping', mapping_parser_func=_parse_chained_types), + "chained_structs": _RuleDesc('mapping', mapping_parser_func=_parse_chained_structs), "strict": _RuleDesc("bool_scalar"), }) @@ -270,9 +350,7 @@ def _parse_enum_values(ctxt, node): field_name_set = set() # type: Set[str] - for node_pair in node.value: - first_node = node_pair[0] - second_node = node_pair[1] + for [first_node, second_node] in node.value: first_name = first_node.value @@ -325,8 +403,8 @@ def _parse_command(ctxt, spec, name, node): _generic_parser(ctxt, node, "command", command, { "description": _RuleDesc('scalar', _RuleDesc.REQUIRED), - "chained_types": _RuleDesc('sequence'), - "chained_structs": _RuleDesc('sequence'), + "chained_types": _RuleDesc('mapping', mapping_parser_func=_parse_chained_types), + "chained_structs": _RuleDesc('mapping', mapping_parser_func=_parse_chained_structs), "fields": _RuleDesc('mapping', mapping_parser_func=_parse_fields), "namespace": _RuleDesc('scalar', _RuleDesc.REQUIRED), "strict": _RuleDesc("bool_scalar"), @@ -374,9 +452,7 @@ def _parse(stream, error_file_name): field_name_set = set() # type: Set[str] - for node_pair in root_node.value: - first_node = node_pair[0] - second_node = node_pair[1] + for [first_node, second_node] in root_node.value: first_name = first_node.value |