def __message_to_schema(self, message_type):
    name = self.__normalized_name(message_type)
    schema = {
        'id': name,
        'type': 'object',
        }
    if message_type.__doc__:
      schema['description'] = message_type.__doc__
    properties = {}
    for field in message_type.all_fields():
      descriptor = {}
      type_info = {}
      if type(field) == messages.MessageField:
        field_type = field.type().__class__
        type_info['$ref'] = self.add_message(field_type)
        if field_type.__doc__:
          descriptor['description'] = field_type.__doc__
      else:
        schema_type = self.__FIELD_TO_SCHEMA_TYPE_MAP.get(
            type(field), self.__DEFAULT_SCHEMA_TYPE)
        if isinstance(schema_type, dict):
          variant_map = schema_type
          variant = getattr(field, 'variant', None)
          if variant in variant_map:
            schema_type = variant_map[variant]
          else:
            schema_type = variant_map[None]
        type_info['type'] = schema_type[0]
        if schema_type[1]:
          type_info['format'] = schema_type[1]
      if type(field) == messages.EnumField:
        sorted_enums = sorted([enum_info for enum_info in field.type],
                              key=lambda enum_info: enum_info.number)
        type_info['enum'] = [enum_info.name for enum_info in sorted_enums]
      if field.required:
        descriptor['required'] = True
      if field.default:
        if type(field) == messages.EnumField:
          descriptor['default'] = str(field.default)
        else:
          descriptor['default'] = field.default
      if field.repeated:
        descriptor['items'] = type_info
        descriptor['type'] = 'array'
      else:
        descriptor.update(type_info)
      properties[field.name] = descriptor
    schema['properties'] = properties
    return schema