# Path: telethon_generator/sourcebuilder.py
# class SourceBuilder:
#     """This class should be used to build .py source files"""
# 
#     def __init__(self, out_stream, indent_size=4):
#         self.current_indent = 0
#         self.on_new_line = False
#         self.indent_size = indent_size
#         self.out_stream = out_stream
# 
#         # Was a new line added automatically before? If so, avoid it
#         self.auto_added_line = False
# 
#     def indent(self):
#         """Indents the current source code line
#            by the current indentation level
#         """
#         self.write(' ' * (self.current_indent * self.indent_size))
# 
#     def write(self, string, *args, **kwargs):
#         """Writes a string into the source code,
#            applying indentation if required
#         """
#         if self.on_new_line:
#             self.on_new_line = False  # We're not on a new line anymore
#             # If the string was not empty, indent; Else probably a new line
#             if string.strip():
#                 self.indent()
# 
#         if args or kwargs:
#             self.out_stream.write(string.format(*args, **kwargs))
#         else:
#             self.out_stream.write(string)
# 
#     def writeln(self, string='', *args, **kwargs):
#         """Writes a string into the source code _and_ appends a new line,
#            applying indentation if required
#         """
#         self.write(string + '\n', *args, **kwargs)
#         self.on_new_line = True
# 
#         # If we're writing a block, increment indent for the next time
#         if string and string[-1] == ':':
#             self.current_indent += 1
# 
#         # Clear state after the user adds a new line
#         self.auto_added_line = False
# 
#     def end_block(self):
#         """Ends an indentation block, leaving an empty line afterwards"""
#         self.current_indent -= 1
# 
#         # If we did not add a new line automatically yet, now it's the time!
#         if not self.auto_added_line:
#             self.writeln()
#             self.auto_added_line = True
# 
#     def __str__(self):
#         self.out_stream.seek(0)
#         return self.out_stream.read()
# 
#     def __enter__(self):
#         return self
# 
#     def __exit__(self, exc_type, exc_val, exc_tb):
#         self.out_stream.close()
# 
# Path: telethon_generator/utils.py
# def snake_to_camel_case(name, suffix=None):
#     # Courtesy of http://stackoverflow.com/a/31531797/4759433
#     result = re.sub(r'_([a-z])', lambda m: m.group(1).upper(), name)
#     result = result[:1].upper() + result[1:].replace('_', '')
#     return result + suffix if suffix else result


import builtins
import functools
import os
import re
import shutil
import struct
from collections import defaultdict
from zlib import crc32
from ..sourcebuilder import SourceBuilder
from ..utils import snake_to_camel_case
                        import_space += '.{}'.format(namespace)

                    if name not in type_names:
                        type_names.add(name)
                        if name == 'date':
                            imports['datetime'] = ['datetime']
                            continue
                        elif import_space not in imports:
                            imports[import_space] = set()
                        imports[import_space].add('Type{}'.format(name))

            # Add imports required for type checking
            if imports:
                builder.writeln('if TYPE_CHECKING:')
                for namespace, names in imports.items():
                    builder.writeln('from {} import {}',
                                    namespace, ', '.join(sorted(names)))

                builder.end_block()

            # Generate the class for every TLObject
            for t in tlobjects:
                _write_source_code(t, kind, builder, type_constructors)
                builder.current_indent = 0

            # Write the type definitions generated earlier.
            builder.writeln()
            for line in type_defs:
                builder.writeln(line)


# Path: telethon_generator/sourcebuilder.py
# class SourceBuilder:
#     """This class should be used to build .py source files"""
# 
#     def __init__(self, out_stream, indent_size=4):
#         self.current_indent = 0
#         self.on_new_line = False
#         self.indent_size = indent_size
#         self.out_stream = out_stream
# 
#         # Was a new line added automatically before? If so, avoid it
#         self.auto_added_line = False
# 
#     def indent(self):
#         """Indents the current source code line
#            by the current indentation level
#         """
#         self.write(' ' * (self.current_indent * self.indent_size))
# 
#     def write(self, string, *args, **kwargs):
#         """Writes a string into the source code,
#            applying indentation if required
#         """
#         if self.on_new_line:
#             self.on_new_line = False  # We're not on a new line anymore
#             # If the string was not empty, indent; Else probably a new line
#             if string.strip():
#                 self.indent()
# 
#         if args or kwargs:
#             self.out_stream.write(string.format(*args, **kwargs))
#         else:
#             self.out_stream.write(string)
# 
#     def writeln(self, string='', *args, **kwargs):
#         """Writes a string into the source code _and_ appends a new line,
#            applying indentation if required
#         """
#         self.write(string + '\n', *args, **kwargs)
#         self.on_new_line = True
# 
#         # If we're writing a block, increment indent for the next time
#         if string and string[-1] == ':':
#             self.current_indent += 1
# 
#         # Clear state after the user adds a new line
#         self.auto_added_line = False
# 
#     def end_block(self):
#         """Ends an indentation block, leaving an empty line afterwards"""
#         self.current_indent -= 1
# 
#         # If we did not add a new line automatically yet, now it's the time!
#         if not self.auto_added_line:
#             self.writeln()
#             self.auto_added_line = True
# 
#     def __str__(self):
#         self.out_stream.seek(0)
#         return self.out_stream.read()
# 
#     def __enter__(self):
#         return self
# 
#     def __exit__(self, exc_type, exc_val, exc_tb):
#         self.out_stream.close()
# 
# Path: telethon_generator/utils.py
# def snake_to_camel_case(name, suffix=None):
#     # Courtesy of http://stackoverflow.com/a/31531797/4759433
#     result = re.sub(r'_([a-z])', lambda m: m.group(1).upper(), name)
#     result = result[:1].upper() + result[1:].replace('_', '')
#     return result + suffix if suffix else result


# Path: telethon_generator/generators/tlobject.py
import builtins
import functools
import os
import re
import shutil
import struct
from collections import defaultdict
from zlib import crc32
from ..sourcebuilder import SourceBuilder
from ..utils import snake_to_camel_case

                        import_space += '.{}'.format(namespace)

                    if name not in type_names:
                        type_names.add(name)
                        if name == 'date':
                            imports['datetime'] = ['datetime']
                            continue
                        elif import_space not in imports:
                            imports[import_space] = set()
                        imports[import_space].add('Type{}'.format(name))

            # Add imports required for type checking
            if imports:
                builder.writeln('if TYPE_CHECKING:')
                for namespace, names in imports.items():
                    builder.writeln('from {} import {}',
                                    namespace, ', '.join(sorted(names)))

                builder.end_block()

            # Generate the class for every TLObject
            for t in tlobjects:
                _write_source_code(t, kind, builder, type_constructors)
                builder.current_indent = 0

            # Write the type definitions generated earlier.
            builder.writeln()
            for line in type_defs:
                builder.writeln(line)


            if not ns and kind == 'TLObject':