+ for k in j["services"]:
+ if k in self.services:
+ raise ParseError("Duplicate service `%s'" % k)
+ self.services[k] = j["services"][k]
+ self.replies.add(self.services[k]["reply"])
+ if "events" in self.services[k]:
+ for x in self.services[k]["events"]:
+ self.events.add(x)
+ if "stream_msg" in self.services[k]:
+ self.streams.add(self.services[k]["stream_msg"])
+ for e in j["enums"]:
+ name = e[0]
+ value_pairs = e[1:-1]
+ enumtype = self.types[e[-1]["enumtype"]]
+ enum = self.enum_class(name, value_pairs, enumtype)
+ self.enums[enum.name] = enum
+ self.logger.debug("Parsed enum: %s" % enum)
+ self.enums_by_json[path].append(enum)
+ for e in j["enumflags"]:
+ name = e[0]
+ value_pairs = e[1:-1]
+ enumtype = self.types[e[-1]["enumtype"]]
+ enum = self.enum_class(name, value_pairs, enumtype)
+ self.enums[enum.name] = enum
+ self.logger.debug("Parsed enumflag: %s" % enum)
+ self.enums_by_json[path].append(enum)
+ exceptions = []
+ progress = 0
+ last_progress = 0
+ while True:
+ for u in j["unions"]:
+ name = u[0]
+ if name in self.unions:
+ progress = progress + 1
+ continue
+ try:
+ type_pairs = [
+ [self.lookup_type_like_id(t), n] for t, n in u[1:]
+ ]
+ union = self.union_class(name, type_pairs, 0)
+ progress = progress + 1
+ except ParseError as e:
+ exceptions.append(e)
+ continue
+ self.unions[union.name] = union
+ self.logger.debug("Parsed union: %s" % union)
+ self.unions_by_json[path].append(union)
+ for t in j["types"]:
+ if t[0] in self.types:
+ progress = progress + 1
+ continue
+ try:
+ type_ = self.struct_type_class(
+ t, self, self.field_class, self.logger
+ )
+ if type_.name in self.types:
+ raise ParseError("Duplicate type `%s'" % type_.name)
+ progress = progress + 1
+ except ParseError as e:
+ exceptions.append(e)
+ continue
+ self.types[type_.name] = type_
+ self.types_by_json[path].append(type_)
+ self.logger.debug("Parsed type: %s" % type_)
+ for name, body in j["aliases"].items():
+ if name in self.aliases:
+ progress = progress + 1
+ continue
+ if "length" in body:
+ array_len = body["length"]
+ else:
+ array_len = None
+ try:
+ t = self.lookup_type_like_id(body["type"])
+ except ParseError as e:
+ exceptions.append(e)
+ continue
+ alias = self.alias_class(name, t, array_len)
+ self.aliases[name] = alias
+ self.logger.debug("Parsed alias: %s" % alias)
+ self.aliases_by_json[path].append(alias)
+ if not exceptions:
+ # finished parsing
+ break
+ if progress <= last_progress:
+ # cannot make forward progress
+ self.exceptions.extend(exceptions)
+ break
+ exceptions = []
+ last_progress = progress
+ progress = 0