def set_enumerated_subtypes(self, subtype_fields, is_catch_all):
assert self._enumerated_subtypes is None,'<STR_LIT>'<EOL>assert isinstance(is_catch_all, bool), type(is_catch_all)<EOL>self._is_catch_all = is_catch_all<EOL>self._enumerated_subtypes = []<EOL>if self.parent_type:<EOL><INDENT>raise InvalidSpec(<EOL>"<STR_LIT>"<EOL>% self.name, self._ast_node.lineno, self._ast_node.path)<EOL><DEDENT>if self.parent_type and not self.parent_type.has_enumerated_subtypes():<EOL><INDENT>raise InvalidSpec(<EOL>"<STR_LIT>" %<EOL>(self.name, self.parent_type.name),<EOL>self._ast_node.lineno, self._ast_node.path)<EOL><DEDENT>enumerated_subtype_names = set()  <EOL>for subtype_field in subtype_fields:<EOL><INDENT>path = subtype_field._ast_node.path<EOL>lineno = subtype_field._ast_node.lineno<EOL>if subtype_field.data_type.name in enumerated_subtype_names:<EOL><INDENT>raise InvalidSpec(<EOL>"<STR_LIT>" %<EOL>subtype_field.data_type.name, lineno, path)<EOL><DEDENT>if subtype_field.data_type.parent_type != self:<EOL><INDENT>raise InvalidSpec(<EOL>"<STR_LIT>" %<EOL>(subtype_field.data_type.name, self.name), lineno, path)<EOL><DEDENT>if subtype_field.name in self._fields_by_name:<EOL><INDENT>orig_field = self._fields_by_name[subtype_field.name]<EOL>raise InvalidSpec(<EOL>"<STR_LIT>" %<EOL>(subtype_field.name, lineno),<EOL>orig_field._ast_node.lineno,<EOL>orig_field._ast_node.path)<EOL><DEDENT>cur_type = self.parent_type<EOL>while cur_type:<EOL><INDENT>if subtype_field.name in cur_type._fields_by_name:<EOL><INDENT>orig_field = cur_type._fields_by_name[subtype_field.name]<EOL>raise InvalidSpec(<EOL>"<STR_LIT>"<EOL>% (subtype_field.name, cur_type.name,<EOL>orig_field._ast_node.path, orig_field._ast_node.lineno),<EOL>lineno, path)<EOL><DEDENT>cur_type = cur_type.parent_type<EOL><DEDENT>self._fields_by_name[subtype_field.name] = subtype_field<EOL>enumerated_subtype_names.add(subtype_field.data_type.name)<EOL>self._enumerated_subtypes.append(subtype_field)<EOL><DEDENT>assert len(self._enumerated_subtypes) > <NUM_LIT:0><EOL>for subtype in self.subtypes:<EOL><INDENT>if subtype.name not in enumerated_subtype_names:<EOL><INDENT>raise InvalidSpec(<EOL>"<STR_LIT>" %<EOL>(self.name, subtype.name),<EOL>self._ast_node.lineno)<EOL><DEDENT><DEDENT>
Sets the list of "enumerated subtypes" for this struct. This differs
from regular subtyping in that each subtype is associated with a tag
that is used in the serialized format to indicate the subtype. Also,
this list of subtypes was explicitly defined in an "inner-union" in the
specification. The list of fields must include all defined subtypes of
this struct.

NOTE(kelkabany): For this to work with upcoming forward references, the
hierarchy of parent types for this struct must have had this method
called on them already.

:type subtype_fields: List[UnionField]