Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def _generate_union_helper(self, u):
name = u.name
namespace = u.namespace
# Unions can be inherited, but don't need to be polymorphic.
# So let's flatten out all the inherited fields.
fields = u.all_fields
if is_struct_type(u) and u.has_enumerated_subtypes():
name = fmt_var(name, export=False) + 'Union'
fields = u.get_enumerated_subtypes()
with self.block('type %s struct' % name):
self.emit('dropbox.Tagged')
for field in fields:
if is_void_type(field.data_type):
continue
self._generate_field(field, union_field=True,
namespace=namespace)
self.emit()
self.emit('// Valid tag values for %s' % fmt_var(u.name))
with self.block('const', delim=('(', ')')):
for field in fields:
self.emit('%s%s = "%s"' % (fmt_var(u.name), fmt_var(field.name), field.name))
self.emit()
def _generate_base_namespace_module(self, api, namespace):
self.emit_raw(base)
routes_base = 'Datatypes and serializers for the {} namespace'.format(namespace.name)
self.emit_wrapped_text(routes_base, prefix='/// ', width=120)
with self.block('open class {}'.format(fmt_class(namespace.name))):
for data_type in namespace.linearize_data_types():
if is_struct_type(data_type):
self._generate_struct_class(namespace, data_type)
self.emit()
elif is_union_type(data_type):
self._generate_union_type(namespace, data_type)
self.emit()
if namespace.routes:
self._generate_route_objects(api.route_schema, namespace)
namespace=namespace, raw=True)
self.emit('var w wrap')
self.emit('var err error')
with self.block('if err = json.Unmarshal(body, &w); err != nil'):
self.emit('return err')
self.emit('u.Tag = w.Tag')
with self.block('switch u.Tag'):
for field in fields:
if is_void_type(field.data_type):
continue
field_name = fmt_var(field.name)
with self.block('case "%s":' % field.name, delim=(None, None)):
if is_union_type(field.data_type):
self.emit('err = json.Unmarshal(w.{0}, &u.{0})'
.format(field_name))
elif is_struct_type(field.data_type) and \
field.data_type.has_enumerated_subtypes():
self.emit("u.{0}, err = Is{1}FromJSON(body)"
.format(field_name, field.data_type.name))
else:
self.emit('err = json.Unmarshal(body, &u.{0})'
.format(field_name))
with self.block("if err != nil"):
self.emit("return err")
self.emit('return nil')
self.emit()
def _generate_hash_func(self, data_type):
with self.block_func(
func='hash', return_type='NSUInteger'):
self.emit('NSUInteger prime = 31;')
self.emit('NSUInteger result = 1;')
self.emit()
if is_union_type(data_type):
with self.block('switch (_tag)'):
for field in data_type.all_fields:
enum_field_name = fmt_enum_name(field.name, data_type)
self.emit('case {}:'.format(enum_field_name))
self._generate_hash_func_helper(data_type, field)
elif is_struct_type(data_type):
for field in data_type.all_fields:
self._generate_hash_func_helper(data_type, field)
self.emit()
self.emit('return prime * result;')
self.emit()
self.emit('#pragma unused(valueDict)')
self.emit('NSString *tag = valueDict[@".tag"];')
self.emit()
first_block = True
for field in union.all_fields:
base_cond = '{} ([tag isEqualToString:@"{}"])'
with self.block(
base_cond.format('if' if first_block else 'else if',
field.name)):
if first_block:
first_block = False
if not is_void_type(field.data_type):
data_type, nullable = unwrap_nullable(field.data_type)
if is_struct_type(
data_type
) and not data_type.has_enumerated_subtypes():
input_value = 'valueDict'
else:
input_value = 'valueDict[@"{}"]'.format(field.name)
if is_primitive_type(data_type):
deserialize_call = input_value
else:
deserialize_call = self._fmt_serialization_call(
data_type, input_value, False)
if nullable:
deserialize_call = '{} ? {} : nil'.format(
input_value, deserialize_call)
def _get_imports_m(self, data_types, default_imports):
"""Emits all necessary implementation file imports for the given Stone data type."""
if not isinstance(data_types, list):
data_types = [data_types]
import_classes = default_imports
for data_type in data_types:
import_classes.append(fmt_class_prefix(data_type))
if data_type.parent_type:
import_classes.append(fmt_class_prefix(data_type.parent_type))
if is_struct_type(
data_type) and data_type.has_enumerated_subtypes():
for _, subtype in data_type.get_all_subtypes_with_tags():
import_classes.append(fmt_class_prefix(subtype))
for field in data_type.all_fields:
data_type, _ = unwrap_nullable(field.data_type)
# unpack list or map
while is_list_type(data_type) or is_map_type(data_type):
data_type = (data_type.value_data_type if
is_map_type(data_type) else data_type.data_type)
if is_user_defined_type(data_type):
import_classes.append(fmt_class_prefix(data_type))
if import_classes:
def _generate_type(self, data_type, extra_parameters):
if is_struct_type(data_type):
self._generate_struct(data_type, extra_parameters)
elif is_union_type(data_type):
self._generate_union(data_type)
def fmt_type(data_type, inside_namespace=None):
"""
Returns a TypeScript type annotation for a data type.
May contain a union of enumerated subtypes.
inside_namespace should be set to the namespace that the type reference
occurs in, or None if this parameter is not relevant.
"""
if is_struct_type(data_type) and data_type.has_enumerated_subtypes():
possible_types = []
possible_subtypes = data_type.get_all_subtypes_with_tags()
for _, subtype in possible_subtypes:
possible_types.append(fmt_polymorphic_type_reference(subtype, inside_namespace))
if data_type.is_catch_all():
possible_types.append(fmt_polymorphic_type_reference(data_type, inside_namespace))
return fmt_union(possible_types)
else:
return fmt_type_name(data_type, inside_namespace)
def _generate_route_method_decl(
self, namespace, route, arg_data_type, request_binary_body,
method_name_suffix='', extra_args=None):
"""Generates the method prototype for a route."""
args = ['self']
if extra_args:
args += extra_args
if request_binary_body:
args.append('f')
if is_struct_type(arg_data_type):
for field in arg_data_type.all_fields:
if is_nullable_type(field.data_type):
args.append('{}=None'.format(field.name))
elif field.has_default:
# TODO(kelkabany): Decide whether we really want to set the
# default in the argument list. This will send the default
# over the wire even if it isn't overridden. The benefit is
# it locks in a default even if it is changed server-side.
if is_user_defined_type(field.data_type):
ns = field.data_type.namespace
else:
ns = None
arg = '{}={}'.format(
field.name,
self._generate_python_value(ns, field.default))
args.append(arg)