#!/usr/bin/env swift import Foundation enum WireFormat: UInt8 { case varint = 0 case fixed64 = 1 case lengthDelimited = 2 case startGroup = 3 case endGroup = 4 case fixed32 = 5 } enum Matchers { case prefix(String, WireFormat) case suffix(String, WireFormat, WireFormat) case contains(String, WireFormat) case contains2(String, WireFormat, WireFormat) case containsAndPackable(String, WireFormat) } // The order of these matters since it is first match that is used. let tests: [Matchers] = [ .prefix("wkt", .lengthDelimited), .prefix("map", .lengthDelimited), .contains2("Group", .startGroup, .endGroup), .containsAndPackable("float", .fixed32), .containsAndPackable("double", .fixed64), .containsAndPackable("fixed64", .fixed64), .containsAndPackable("fixed", .fixed32), .containsAndPackable("int64", .varint), .containsAndPackable("int32", .varint), .containsAndPackable("bool", .varint), .containsAndPackable("enum", .varint), .contains("bytes", .lengthDelimited), .contains("string", .lengthDelimited), .contains("message", .lengthDelimited), // The single fields in the Groups. .contains("group_field", .varint), ] func escapedVarint(_ x: Int) -> String { var escaped = String() var v = x while v > 127 { escaped.append(String(format: "\\x%02x", UInt8(v & 0x7f | 0x80))) v >>= 7 } escaped.append(String(format: "\\x%02x", UInt8(v))) return escaped } func outputTag(_ fieldNum: Int, as wireformat: WireFormat) { let tag = UInt32(truncatingIfNeeded: fieldNum) << 3 | UInt32(wireformat.rawValue) print("\"\(escapedVarint(Int(tag)))\"") } if CommandLine.arguments.count != 2 { print("Expected only to get the proto file path as an argument") exit(1) } print("# Tags for all the fields") let protoFile = try! String(contentsOfFile: CommandLine.arguments[1], encoding: .utf8) let re = try NSRegularExpression(pattern: #"^ *.+ +(\w+) += (\d+)"#, options: [.anchorsMatchLines]) let range = NSRange(protoFile.startIndex..