Fix the wire compatibility check for proto fields

Review the AI's codeMedium15 minGoogle style

Your task

An AI agent tidied up the .proto files of a gRPC service and said it only "reorganized fields and improved comments". Protobuf encodes each field by its number and type, never by its name or position, and many older clients still talk to this service. So you compare the old and new field descriptors before anything ships.

An assistant wrote detect_proto_breaks(old_fields, new_fields). It is in the editor. It has a bug. Find it and fix it.

Input and output:

  • old_fields and new_fields: the message's fields before and after the change, each written number|name|type. In new_fields, an entry named reserved marks a number that was retired on purpose.
  • Return the changes that break old clients.

Rules the tests check:

  • Split an entry on |. Skip it unless it has exactly 3 parts and the number is one or more digits from 0 to 9. Read the number as a whole number.
  • In old_fields, skip entries named reserved. In new_fields, an entry named reserved reserves its number and is not a field.
  • If a number appears twice among one side's fields, keep only its first entry.
  • For each old field, by its number:
    • new_fields has no field with that number, and the number is not reserved: removed:<number>
    • new_fields has a field with that number and a different type: type_changed:<number>
  • renumbered:<name> for each old field whose name appears in new_fields at a different number. If a name appears at more than one new number, use the first. Report each name once.
  • A field renamed at the same number is fine, and so is a new field.
  • Output the number findings first, by number ascending, then the renumbered findings, sorted by name in plain string order.

Examples

detect_proto_breaks(old_fields: list[str], new_fields: list[str]) -> list[str]
Example 1
Inputdetect_proto_breaks(["1|user_id|int64", "2|email|string", "3|created_at|int64"], ["1|user_id|int64", "2|email_address|string", "3|created_at|int64"])
Output[]
Example 2
Inputdetect_proto_breaks(["1|user_id|int64", "2|email|string", "3|score|int32"], ["1|user_id|int64", "2|score|int32", "3|email|string"])
Output["type_changed:2", "type_changed:3", "renumbered:email", "renumbered:score"]