def _resolve_type(self, env, type_ref, enforce_fully_defined=False):
loc = type_ref.lineno, type_ref.path<EOL>orig_namespace_name = env.namespace_name<EOL>if type_ref.ns:<EOL><INDENT>if type_ref.ns not in env:<EOL><INDENT>raise InvalidSpec(<EOL>'<STR_LIT>' % quote(type_ref.ns), *loc)<EOL><DEDENT>env = env[type_ref.ns]<EOL>if not isinstance(env, Environment):<EOL><INDENT>raise InvalidSpec(<EOL>'<STR_LIT>' % quote(type_ref.ns), *loc)<EOL><DEDENT><DEDENT>if type_ref.name not in env:<EOL><INDENT>raise InvalidSpec(<EOL>'<STR_LIT>' % quote(type_ref.name), *loc)<EOL><DEDENT>obj = env[type_ref.name]<EOL>if obj is Void and type_ref.nullable:<EOL><INDENT>raise InvalidSpec('<STR_LIT>',<EOL>*loc)<EOL><DEDENT>elif inspect.isclass(obj):<EOL><INDENT>resolved_data_type_args = self._resolve_args(env, type_ref.args)<EOL>data_type = self._instantiate_data_type(<EOL>obj, resolved_data_type_args, (type_ref.lineno, type_ref.path))<EOL><DEDENT>elif isinstance(obj, ApiRoutesByVersion):<EOL><INDENT>raise InvalidSpec('<STR_LIT>',<EOL>*loc)<EOL><DEDENT>elif type_ref.args[<NUM_LIT:0>] or type_ref.args[<NUM_LIT:1>]:<EOL><INDENT>raise InvalidSpec('<STR_LIT>'<EOL>'<STR_LIT>' %<EOL>quote(type_ref.name),<EOL>*loc)<EOL><DEDENT>else:<EOL><INDENT>data_type = env[type_ref.name]<EOL><DEDENT>if type_ref.ns:<EOL><INDENT>namespace = self.api.ensure_namespace(orig_namespace_name)<EOL>if isinstance(data_type, UserDefined):<EOL><INDENT>namespace.add_imported_namespace(<EOL>self.api.ensure_namespace(type_ref.ns),<EOL>imported_data_type=True)<EOL><DEDENT>elif isinstance(data_type, Alias):<EOL><INDENT>namespace.add_imported_namespace(<EOL>self.api.ensure_namespace(type_ref.ns),<EOL>imported_alias=True)<EOL><DEDENT><DEDENT>if (enforce_fully_defined and isinstance(data_type, UserDefined) and<EOL>data_type._is_forward_ref):<EOL><INDENT>if data_type in self._resolution_in_progress:<EOL><INDENT>raise InvalidSpec(<EOL>'<STR_LIT>' %<EOL>quote(type_ref.name), *loc)<EOL><DEDENT>self._resolution_in_progress.add(data_type)<EOL>if isinstance(data_type, Struct):<EOL><INDENT>self._populate_struct_type_attributes(env, data_type)<EOL><DEDENT>elif isinstance(data_type, Union):<EOL><INDENT>self._populate_union_type_attributes(env, data_type)<EOL><DEDENT>self._resolution_in_progress.remove(data_type)<EOL><DEDENT>if type_ref.nullable:<EOL><INDENT>unwrapped_dt, _ = unwrap_aliases(data_type)<EOL>if isinstance(unwrapped_dt, Nullable):<EOL><INDENT>raise InvalidSpec(<EOL>'<STR_LIT>',<EOL>*loc)<EOL><DEDENT>data_type = Nullable(data_type)<EOL><DEDENT>return data_type<EOL>
Resolves the data type referenced by type_ref.

If `enforce_fully_defined` is True, then the referenced type must be
fully populated (fields, parent_type, ...), and not simply a forward
reference.