def _emit_route(self, namespace, route, req_obj_name, extra_args=None, extra_docs=None): arg_list, doc_list = self._get_route_args(namespace, route) extra_args = extra_args or [] extra_docs = extra_docs or [] arg_type = fmt_type(route.arg_data_type) func_name = fmt_func(route.name) if route.doc: route_doc = self.process_doc(route.doc, self._docf) else: route_doc = 'The {} route'.format(func_name) self.emit_wrapped_text(route_doc, prefix='/// ', width=120) self.emit('///') for name, doc in doc_list + extra_docs: param_doc = '- parameter {}: {}'.format(name, doc if doc is not None else undocumented) self.emit_wrapped_text(param_doc, prefix='/// ', width=120) self.emit('///') output = (' - returns: Through the response callback, the caller will ' + 'receive a `{}` object on success or a `{}` object on failure.') output = output.format(fmt_type(route.result_data_type), fmt_type(route.error_data_type)) self.emit_wrapped_text(output, prefix='/// ', width=120) func_args = [ ('route', '{}.{}'.format(fmt_class(namespace.name), func_name)), ] client_args = [] return_args = [('route', 'route')] for name, value, typ in extra_args: arg_list.append((name, typ)) func_args.append((name, value)) client_args.append((name, value)) rtype = fmt_serial_type(route.result_data_type) etype = fmt_serial_type(route.error_data_type) self._maybe_generate_deprecation_warning(route) with self.function_block('public func {}'.format(func_name), args=self._func_args(arg_list, force_first=True), return_type='{}<{}, {}>'.format(req_obj_name, rtype, etype)): self.emit('let route = {}.{}'.format(fmt_class(namespace.name), func_name)) if is_struct_type(route.arg_data_type): args = [(name, name) for name, _ in self._struct_init_args(route.arg_data_type)] func_args += [('serverArgs', '{}({})'.format(arg_type, self._func_args(args)))] self.emit('let serverArgs = {}({})'.format(arg_type, self._func_args(args))) elif is_union_type(route.arg_data_type): self.emit('let serverArgs = {}'.format(fmt_var(route.arg_data_type.name))) if not is_void_type(route.arg_data_type): return_args += [('serverArgs', 'serverArgs')] return_args += client_args self.emit('return client.request({})'.format(self._func_args(return_args, not_init=True))) self.emit()
def _generate_struct_class(self, namespace, data_type): if data_type.doc: doc = self.process_doc(data_type.doc, self._docf) else: doc = 'The {} struct'.format(fmt_class(data_type.name)) self.emit_wrapped_text(doc, prefix='/// ', width=120) protocols = [] if not data_type.parent_type: protocols.append('CustomStringConvertible') with self.class_block(data_type, protocols=protocols): for field in data_type.fields: fdoc = self.process_doc(field.doc, self._docf) if field.doc else undocumented self.emit_wrapped_text(fdoc, prefix='/// ', width=120) self.emit('public let {}: {}'.format( fmt_var(field.name), fmt_type(field.data_type), )) self._generate_struct_init(namespace, data_type) decl = 'public var' if not data_type.parent_type else 'public override var' with self.block('{} description: String'.format(decl)): cls = fmt_class(data_type.name)+'Serializer' self.emit('return "\(SerializeUtil.prepareJSONForSerialization' + '({}().serialize(self)))"'.format(cls)) self._generate_struct_class_serializer(namespace, data_type)
def _generate_struct_class(self, namespace, data_type): if data_type.doc: doc = self.process_doc(data_type.doc, self._docf) else: doc = 'The {} struct'.format(fmt_class(data_type.name)) self.emit_wrapped_text(doc, prefix='/// ', width=120) protocols = [] if not data_type.parent_type: protocols.append('CustomStringConvertible') with self.class_block(data_type, protocols=protocols): for field in data_type.fields: fdoc = self.process_doc( field.doc, self._docf) if field.doc else undocumented self.emit_wrapped_text(fdoc, prefix='/// ', width=120) self.emit('open let {}: {}'.format( fmt_var(field.name), fmt_type(field.data_type), )) self._generate_struct_init(namespace, data_type) decl = 'open var' if not data_type.parent_type else 'open override var' with self.block('{} description: String'.format(decl)): cls = fmt_class(data_type.name) + 'Serializer' self.emit( 'return "\\(SerializeUtil.prepareJSONForSerialization' + '({}().serialize(self)))"'.format(cls)) self._generate_struct_class_serializer(namespace, data_type)
def class_block(self, thing, protocols=None): protocols = protocols or [] extensions = [] if isinstance(thing, DataType): name = fmt_class(thing.name) if thing.parent_type: extensions.append(fmt_type(thing.parent_type)) else: name = thing extensions.extend(protocols) extend_suffix = ': {}'.format(', '.join(extensions)) if extensions else '' with self.block('open class {}{}'.format(name, extend_suffix)): yield
def class_block(self, thing, protocols=None): protocols = protocols or [] extensions = [] if isinstance(thing, DataType): name = fmt_class(thing.name) if thing.parent_type: extensions.append(fmt_type(thing.parent_type)) else: name = thing extensions.extend(protocols) extend_suffix = ': {}'.format(', '.join(extensions)) if extensions else '' with self.block('public class {}{}'.format(name, extend_suffix)): yield
def _generate_enumerated_subtype_serializer(self, namespace, data_type): with self.block('switch value'): for tags, subtype in data_type.get_all_subtypes_with_tags(): assert len(tags) == 1, tags tag = tags[0] tagvar = fmt_var(tag) self.emit('case let {} as {}:'.format(tagvar, fmt_type(subtype))) with self.indent(): with self.block( 'for (k,v) in Serialization.getFields({}.serialize({}))' .format(fmt_serial_obj(subtype), tagvar)): self.emit('output[k] = v') self.emit('output[".tag"] = .Str("{}")'.format(tag)) self.emit( 'default: fatalError("Tried to serialize unexpected subtype")')
def _generate_enumerated_subtype_serializer(self, namespace, data_type): with self.block('switch value'): for tags, subtype in data_type.get_all_subtypes_with_tags(): assert len(tags) == 1, tags tag = tags[0] tagvar = fmt_var(tag) self.emit('case let {} as {}:'.format( tagvar, fmt_type(subtype) )) with self.indent(): with self.block('for (k,v) in Serialization.getFields({}.serialize({}))'.format( fmt_serial_obj(subtype), tagvar )): self.emit('output[k] = v') self.emit('output[".tag"] = .Str("{}")'.format(tag)) self.emit('default: fatalError("Tried to serialize unexpected subtype")')
def _get_route_args(self, namespace, route): data_type = route.arg_data_type arg_type = fmt_type(data_type) if is_struct_type(data_type): arg_list = self._struct_init_args(data_type, namespace=namespace) doc_list = [(fmt_var(f.name), self.process_doc(f.doc, self._docf) if f.doc else undocumented) for f in data_type.fields if f.doc] elif is_union_type(data_type): arg_list = [(fmt_var(data_type.name), '{}.{}'.format( fmt_class(namespace.name), fmt_class(data_type.name)))] doc_list = [(fmt_var(data_type.name), self.process_doc(data_type.doc, self._docf) if data_type.doc else 'The {} union'.format(fmt_class(data_type.name)))] else: arg_list = [] if is_void_type(data_type) else [('request', arg_type)] doc_list = [] return arg_list, doc_list
def _struct_init_args(self, data_type, namespace=None): # pylint: disable=unused-argument args = [] for field in data_type.all_fields: name = fmt_var(field.name) value = fmt_type(field.data_type) data_type, nullable = unwrap_nullable(field.data_type) if field.has_default: if is_union_type(data_type): default = '.{}'.format(fmt_var(field.default.tag_name)) else: default = fmt_obj(field.default) value += ' = {}'.format(default) elif nullable: value += ' = nil' arg = (name, value) args.append(arg) return args
def _struct_init_args(self, data_type, namespace=None): args = [] for field in data_type.all_fields: name = fmt_var(field.name) value = fmt_type(field.data_type) data_type, nullable = unwrap_nullable(field.data_type) if field.has_default: if is_union_type(data_type): default = '.{}'.format(fmt_class(field.default.tag_name)) else: default = fmt_obj(field.default) value += ' = {}'.format(default) elif nullable: value += ' = nil' arg = (name, value) args.append(arg) return args
def _get_route_args(self, namespace, route): data_type = route.arg_data_type arg_type = fmt_type(data_type) if is_struct_type(data_type): arg_list = self._struct_init_args(data_type, namespace=namespace) doc_list = [(fmt_var(f.name), self.process_doc(f.doc, self._docf) if f.doc else undocumented) for f in data_type.fields if f.doc] elif is_union_type(data_type): arg_list = [(fmt_var(data_type.name), '{}.{}'.format(fmt_class(namespace.name), fmt_class(data_type.name)))] doc_list = [ (fmt_var(data_type.name), self.process_doc(data_type.doc, self._docf) if data_type.doc else 'The {} union'.format(fmt_class(data_type.name))) ] else: arg_list = [] if is_void_type(data_type) else [('request', arg_type)] doc_list = [] return arg_list, doc_list
def _format_tag_type(self, namespace, data_type): if is_void_type(data_type): return '' else: return '({})'.format(fmt_type(data_type))
def _format_tag_type(self, namespace, data_type): # pylint: disable=unused-argument if is_void_type(data_type): return '' else: return '({})'.format(fmt_type(data_type))
def _emit_route(self, namespace, route, req_obj_name, extra_args=None, extra_docs=None): arg_list, doc_list = self._get_route_args(namespace, route) extra_args = extra_args or [] extra_docs = extra_docs or [] arg_type = fmt_type(route.arg_data_type) func_name = fmt_func(route.name) if route.doc: route_doc = self.process_doc(route.doc, self._docf) else: route_doc = 'The {} route'.format(func_name) self.emit_wrapped_text(route_doc, prefix='/// ', width=120) self.emit('///') for name, doc in doc_list + extra_docs: param_doc = '- parameter {}: {}'.format( name, doc if doc is not None else undocumented) self.emit_wrapped_text(param_doc, prefix='/// ', width=120) self.emit('///') output = ( ' - returns: Through the response callback, the caller will ' + 'receive a `{}` object on success or a `{}` object on failure.') output = output.format(fmt_type(route.result_data_type), fmt_type(route.error_data_type)) self.emit_wrapped_text(output, prefix='/// ', width=120) func_args = [ ('route', '{}.{}'.format(fmt_class(namespace.name), func_name)), ] client_args = [] return_args = [('route', 'route')] for name, value, typ in extra_args: arg_list.append((name, typ)) func_args.append((name, value)) client_args.append((name, value)) rtype = fmt_serial_type(route.result_data_type) etype = fmt_serial_type(route.error_data_type) self._maybe_generate_deprecation_warning(route) with self.function_block( '@discardableResult open func {}'.format(func_name), args=self._func_args(arg_list, force_first=False), return_type='{}<{}, {}>'.format(req_obj_name, rtype, etype)): self.emit('let route = {}.{}'.format(fmt_class(namespace.name), func_name)) if is_struct_type(route.arg_data_type): args = [ (name, name) for name, _ in self._struct_init_args(route.arg_data_type) ] func_args += [ ('serverArgs', '{}({})'.format(arg_type, self._func_args(args))) ] self.emit('let serverArgs = {}({})'.format( arg_type, self._func_args(args))) elif is_union_type(route.arg_data_type): self.emit('let serverArgs = {}'.format( fmt_var(route.arg_data_type.name))) if not is_void_type(route.arg_data_type): return_args += [('serverArgs', 'serverArgs')] return_args += client_args self.emit('return client.request({})'.format( self._func_args(return_args, not_init=True))) self.emit()