-def generate_header(dependencies, headername, enums, messages, extensions, options):
- '''Generate content for a header file.
- Generates strings, which should be concatenated and stored to file.
- '''
-
- yield '/* Automatically generated nanopb header */\n'
- yield '/* Generated by %s at %s. */\n\n' % (nanopb_version, time.asctime())
-
- symbol = make_identifier(headername)
- yield '#ifndef _PB_%s_\n' % symbol
- yield '#define _PB_%s_\n' % symbol
- try:
- yield options.libformat % ('pb.h')
- except TypeError:
- # no %s specified - use whatever was passed in as options.libformat
- yield options.libformat
- yield '\n'
-
- for dependency in dependencies:
- noext = os.path.splitext(dependency)[0]
- yield options.genformat % (noext + '.' + options.extension + '.h')
+class ProtoFile:
+ def __init__(self, fdesc, file_options):
+ '''Takes a FileDescriptorProto and parses it.'''
+ self.fdesc = fdesc
+ self.file_options = file_options
+ self.dependencies = {}
+ self.parse()
+
+ # Some of types used in this file probably come from the file itself.
+ # Thus it has implicit dependency on itself.
+ self.add_dependency(self)
+
+ def parse(self):
+ self.enums = []
+ self.messages = []
+ self.extensions = []
+
+ if self.fdesc.package:
+ base_name = Names(self.fdesc.package.split('.'))
+ else:
+ base_name = Names()
+
+ for enum in self.fdesc.enum_type:
+ enum_options = get_nanopb_suboptions(enum, self.file_options, base_name + enum.name)
+ self.enums.append(Enum(base_name, enum, enum_options))
+
+ for names, message in iterate_messages(self.fdesc, base_name):
+ message_options = get_nanopb_suboptions(message, self.file_options, names)
+
+ if message_options.skip_message:
+ continue
+
+ self.messages.append(Message(names, message, message_options))
+ for enum in message.enum_type:
+ enum_options = get_nanopb_suboptions(enum, message_options, names + enum.name)
+ self.enums.append(Enum(names, enum, enum_options))
+
+ for names, extension in iterate_extensions(self.fdesc, base_name):
+ field_options = get_nanopb_suboptions(extension, self.file_options, names + extension.name)
+ if field_options.type != nanopb_pb2.FT_IGNORE:
+ self.extensions.append(ExtensionField(names, extension, field_options))
+
+ def add_dependency(self, other):
+ for enum in other.enums:
+ self.dependencies[str(enum.names)] = enum
+
+ for msg in other.messages:
+ self.dependencies[str(msg.name)] = msg
+
+ # Fix field default values where enum short names are used.
+ for enum in other.enums:
+ if not enum.options.long_names:
+ for message in self.messages:
+ for field in message.fields:
+ if field.default in enum.value_longnames:
+ idx = enum.value_longnames.index(field.default)
+ field.default = enum.values[idx][0]
+
+ # Fix field data types where enums have negative values.
+ for enum in other.enums:
+ if not enum.has_negative():
+ for message in self.messages:
+ for field in message.fields:
+ if field.pbtype == 'ENUM' and field.ctype == enum.names:
+ field.pbtype = 'UENUM'
+
+ def generate_header(self, includes, headername, options):
+ '''Generate content for a header file.
+ Generates strings, which should be concatenated and stored to file.
+ '''
+
+ yield '/* Automatically generated nanopb header */\n'
+ if options.notimestamp:
+ yield '/* Generated by %s */\n\n' % (nanopb_version)
+ else:
+ yield '/* Generated by %s at %s. */\n\n' % (nanopb_version, time.asctime())
+
+ symbol = make_identifier(headername)
+ yield '#ifndef PB_%s_INCLUDED\n' % symbol
+ yield '#define PB_%s_INCLUDED\n' % symbol
+ try:
+ yield options.libformat % ('pb.h')
+ except TypeError:
+ # no %s specified - use whatever was passed in as options.libformat
+ yield options.libformat