+# ---------------------------------------------------------------------------
+# 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.fields = []
+
+ 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):
+ prev_field_name = prev_field_name or self.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
+