+ def tags(self):
+ '''Return the #define for the tag number of this field.'''
+ identifier = '%s_tag' % self.fullname
+ return '#define %-40s %d\n' % (identifier, self.tag)
+
+ def extension_decl(self):
+ '''Declaration of the extension type in the .pb.h file'''
+ if self.skip:
+ msg = '/* Extension field %s was skipped because only "optional"\n' % self.fullname
+ msg +=' type of extension fields is currently supported. */\n'
+ return msg
+
+ return ('extern const pb_extension_type_t %s; /* field type: %s */\n' %
+ (self.fullname, str(self).strip()))
+
+ def extension_def(self):
+ '''Definition of the extension type in the .pb.c file'''
+
+ if self.skip:
+ return ''
+
+ result = 'typedef struct {\n'
+ result += str(self)
+ result += '\n} %s;\n\n' % self.struct_name
+ result += ('static const pb_field_t %s_field = \n %s;\n\n' %
+ (self.fullname, self.pb_field_t(None)))
+ result += 'const pb_extension_type_t %s = {\n' % self.fullname
+ result += ' NULL,\n'
+ result += ' NULL,\n'
+ result += ' &%s_field\n' % self.fullname
+ result += '};\n'
+ return result
+
+
+# ---------------------------------------------------------------------------
+# Generation of oneofs (unions)
+# ---------------------------------------------------------------------------
+
+class OneOf(Field):
+ def __init__(self, struct_name, oneof_desc):
+ self.struct_name = struct_name
+ self.name = oneof_desc.name
+ self.ctype = 'union'
+ self.pbtype = 'oneof'
+ self.fields = []
+ self.allocation = 'ONEOF'
+ self.default = None
+ self.rules = 'ONEOF'
+
+ def add_field(self, field):
+ if field.allocation == 'CALLBACK':
+ raise Exception("Callback fields inside of oneof are not supported"
+ + " (field %s)" % field.name)
+
+ field.union_name = self.name
+ field.rules = 'ONEOF'
+ self.fields.append(field)
+ self.fields.sort(key = lambda f: f.tag)
+
+ # Sort by the lowest tag number inside union
+ self.tag = min([f.tag for f in self.fields])
+
+ def __cmp__(self, other):
+ return cmp(self.tag, other.tag)
+
+ def __str__(self):
+ result = ''
+ if self.fields:
+ result += ' pb_size_t which_' + self.name + ";\n"
+ result += ' union {\n'
+ for f in self.fields:
+ result += ' ' + str(f).replace('\n', '\n ') + '\n'
+ result += ' } ' + self.name + ';'
+ return result
+
+ def types(self):
+ return ''.join([f.types() for f in self.fields])
+
+ def get_dependencies(self):
+ deps = []
+ for f in self.fields:
+ deps += f.get_dependencies()
+ return deps
+
+ def get_initializer(self, null_init):
+ return '0, {' + self.fields[0].get_initializer(null_init) + '}'
+
+ def default_decl(self, declaration_only = False):
+ return None
+
+ def tags(self):
+ return '\n'.join([f.tags() for f in self.fields])
+
+ def pb_field_t(self, prev_field_name):
+ result = ',\n'.join([f.pb_field_t(prev_field_name) for f in self.fields])
+ return result
+
+ def largest_field_value(self):
+ return max([f.largest_field_value() for f in self.fields])
+
+ def encoded_size(self, allmsgs):
+ largest = EncodedSize(0)
+ for f in self.fields:
+ size = f.encoded_size(allmsgs)
+ if size is None:
+ return None
+ elif size.symbols:
+ return None # Cannot resolve maximum of symbols
+ elif size.value > largest.value:
+ largest = size
+
+ return largest