diff --git a/tests/json/test.upbdefs.c b/tests/json/test.upbdefs.c index a2fe2b177b..933fe5fe34 100644 --- a/tests/json/test.upbdefs.c +++ b/tests/json/test.upbdefs.c @@ -20,14 +20,14 @@ static upb_inttable reftables[92]; #endif static const upb_msgdef msgs[8] = { - UPB_MSGDEF_INIT("upb.test.json.SubMessage", 4, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[0], 2, 1), UPB_STRTABLE_INIT(1, 3, UPB_CTYPE_PTR, 2, &strentries[0]), false, UPB_SYNTAX_PROTO3, &reftables[0], &reftables[1]), - UPB_MSGDEF_INIT("upb.test.json.TestMessage", 73, 8, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[2], 26, 24), UPB_STRTABLE_INIT(24, 31, UPB_CTYPE_PTR, 5, &strentries[4]), false, UPB_SYNTAX_PROTO3, &reftables[2], &reftables[3]), - UPB_MSGDEF_INIT("upb.test.json.TestMessage.MapBoolStringEntry", 7, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[28], 3, 2), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[36]), true, UPB_SYNTAX_PROTO3, &reftables[4], &reftables[5]), - UPB_MSGDEF_INIT("upb.test.json.TestMessage.MapInt32StringEntry", 7, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[31], 3, 2), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[40]), true, UPB_SYNTAX_PROTO3, &reftables[6], &reftables[7]), - UPB_MSGDEF_INIT("upb.test.json.TestMessage.MapStringBoolEntry", 7, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[34], 3, 2), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[44]), true, UPB_SYNTAX_PROTO3, &reftables[8], &reftables[9]), - UPB_MSGDEF_INIT("upb.test.json.TestMessage.MapStringInt32Entry", 7, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[37], 3, 2), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[48]), true, UPB_SYNTAX_PROTO3, &reftables[10], &reftables[11]), - UPB_MSGDEF_INIT("upb.test.json.TestMessage.MapStringMsgEntry", 8, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[40], 3, 2), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[52]), true, UPB_SYNTAX_PROTO3, &reftables[12], &reftables[13]), - UPB_MSGDEF_INIT("upb.test.json.TestMessage.MapStringStringEntry", 9, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[43], 3, 2), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[56]), true, UPB_SYNTAX_PROTO3, &reftables[14], &reftables[15]), + UPB_MSGDEF_INIT("upb.test.json.SubMessage", 4, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[0], 2, 1), UPB_STRTABLE_INIT(1, 3, UPB_CTYPE_PTR, 2, &strentries[0]), false, UPB_SYNTAX_PROTO3, UPB_WELLKNOWN_UNSPECIFIED, &reftables[0], &reftables[1]), + UPB_MSGDEF_INIT("upb.test.json.TestMessage", 73, 8, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[2], 26, 24), UPB_STRTABLE_INIT(24, 31, UPB_CTYPE_PTR, 5, &strentries[4]), false, UPB_SYNTAX_PROTO3, UPB_WELLKNOWN_UNSPECIFIED, &reftables[2], &reftables[3]), + UPB_MSGDEF_INIT("upb.test.json.TestMessage.MapBoolStringEntry", 7, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[28], 3, 2), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[36]), true, UPB_SYNTAX_PROTO3, UPB_WELLKNOWN_UNSPECIFIED, &reftables[4], &reftables[5]), + UPB_MSGDEF_INIT("upb.test.json.TestMessage.MapInt32StringEntry", 7, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[31], 3, 2), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[40]), true, UPB_SYNTAX_PROTO3, UPB_WELLKNOWN_UNSPECIFIED, &reftables[6], &reftables[7]), + UPB_MSGDEF_INIT("upb.test.json.TestMessage.MapStringBoolEntry", 7, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[34], 3, 2), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[44]), true, UPB_SYNTAX_PROTO3, UPB_WELLKNOWN_UNSPECIFIED, &reftables[8], &reftables[9]), + UPB_MSGDEF_INIT("upb.test.json.TestMessage.MapStringInt32Entry", 7, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[37], 3, 2), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[48]), true, UPB_SYNTAX_PROTO3, UPB_WELLKNOWN_UNSPECIFIED, &reftables[10], &reftables[11]), + UPB_MSGDEF_INIT("upb.test.json.TestMessage.MapStringMsgEntry", 8, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[40], 3, 2), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[52]), true, UPB_SYNTAX_PROTO3, UPB_WELLKNOWN_UNSPECIFIED, &reftables[12], &reftables[13]), + UPB_MSGDEF_INIT("upb.test.json.TestMessage.MapStringStringEntry", 9, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[43], 3, 2), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[56]), true, UPB_SYNTAX_PROTO3, UPB_WELLKNOWN_UNSPECIFIED, &reftables[14], &reftables[15]), }; static const upb_fielddef fields[37] = { diff --git a/tools/amalgamate.py b/tools/amalgamate.py index d3807c62b1..4739a94e5d 100755 --- a/tools/amalgamate.py +++ b/tools/amalgamate.py @@ -18,14 +18,14 @@ class Amalgamator: self.output_c.write("// Amalgamated source file\n") self.output_c.write('#include "upb.h"\n') - self.output_c.write('#include "upb/port_def.inc"\n') + self.output_c.write(open("upb/port_def.inc").read()) self.output_h.write("// Amalgamated source file\n") - self.output_h.write('#include "upb/port_def.inc"\n') + self.output_h.write(open("upb/port_def.inc").read()) def finish(self): - self.output_c.write('#include "upb/port_undef.inc"\n') - self.output_h.write('#include "upb/port_undef.inc"\n') + self.output_c.write(open("upb/port_undef.inc").read()) + self.output_h.write(open("upb/port_undef.inc").read()) def _process_file(self, infile_name, outfile): for line in open(infile_name): diff --git a/tools/dump_cinit.lua b/tools/dump_cinit.lua new file mode 100644 index 0000000000..93ee12e57f --- /dev/null +++ b/tools/dump_cinit.lua @@ -0,0 +1,749 @@ +--[[ + + Routines for dumping internal data structures into C initializers + that can be compiled into a .o file. + +--]] + +local upbtable = require "upb.table" +local upb = require "upb" +local export = {} + +-- A tiny little abstraction that decouples the dump_* functions from +-- what they're writing to (appending to a string, writing to file I/O, etc). +-- This could possibly matter since naive string building is O(n^2) in the +-- number of appends. +function export.str_appender() + local str = "" + local function append(fmt, ...) + str = str .. string.format(fmt, ...) + end + local function get() + return str + end + return append, get +end + +function export.file_appender(file) + local f = file + local function append(fmt, ...) + f:write(string.format(fmt, ...)) + end + return append +end + +function handler_types(base) + local ret = {} + for k, _ in pairs(base) do + if string.find(k, "^" .. "HANDLER_") then + ret[#ret + 1] = k + end + end + return ret +end + +function octchar(num) + assert(num < 8) + local idx = num + 1 -- 1-based index + return string.sub("01234567", idx, idx) +end + +function c_escape(num) + assert(num < 256) + return string.format("\\%s%s%s", + octchar(math.floor(num / 64)), + octchar(math.floor(num / 8) % 8), + octchar(num % 8)); +end + +-- const(f, label) -> UPB_LABEL_REPEATED, where f:label() == upb.LABEL_REPEATED +function const(obj, name, base) + local val = obj[name] + base = base or upb + + -- Support both f:label() and f.label. + if type(val) == "function" then + val = val(obj) + end + + for k, v in pairs(base) do + if v == val and string.find(k, "^" .. string.upper(name)) then + return "UPB_" .. k + end + end + assert(false, "Couldn't find UPB_" .. string.upper(name) .. + " constant for value: " .. val) +end + +function sortedkeys(tab) + arr = {} + for key in pairs(tab) do + arr[#arr + 1] = key + end + table.sort(arr) + return arr +end + +function sorted_defs(defs) + local sorted = {} + + for def in defs do + if def.type == deftype then + sorted[#sorted + 1] = def + end + end + + table.sort(sorted, + function(a, b) return a:full_name() < b:full_name() end) + + return sorted +end + +function constlist(pattern) + local ret = {} + for k, v in pairs(upb) do + if string.find(k, "^" .. pattern) then + ret[k] = v + end + end + return ret +end + +function boolstr(val) + if val == true then + return "true" + elseif val == false then + return "false" + else + assert(false, "Bad bool value: " .. tostring(val)) + end +end + +--[[ + + LinkTable: an object that tracks all linkable objects and their offsets to + facilitate linking. + +--]] + +local LinkTable = {} +function LinkTable:new(types) + local linktab = { + types = types, + table = {}, -- ptr -> {type, 0-based offset} + obj_arrays = {} -- Establishes the ordering for each object type + } + for type, _ in pairs(types) do + linktab.obj_arrays[type] = {} + end + setmetatable(linktab, {__index = LinkTable}) -- Inheritance + return linktab +end + +-- Adds a new object to the sequence of objects of this type. +function LinkTable:add(objtype, ptr, obj) + obj = obj or ptr + assert(self.table[obj] == nil) + assert(self.types[objtype]) + local arr = self.obj_arrays[objtype] + self.table[ptr] = {objtype, #arr} + arr[#arr + 1] = obj +end + +-- Returns a C symbol name for the given objtype and offset. +function LinkTable:csym(objtype, offset) + local typestr = assert(self.types[objtype]) + return string.format("%s[%d]", typestr, offset) +end + +-- Returns the address of the given C object. +function LinkTable:addr(obj) + if obj == upbtable.NULL then + return "NULL" + else + local tabent = assert(self.table[obj], "unknown object: " .. tostring(obj)) + return "&" .. self:csym(tabent[1], tabent[2]) + end +end + +-- Returns an array declarator indicating how many objects have been added. +function LinkTable:cdecl(objtype) + return self:csym(objtype, #self.obj_arrays[objtype]) +end + +function LinkTable:objs(objtype) + -- Return iterator function, allowing use as: + -- for obj in linktable:objs(type) do + -- -- ... + -- done + local array = self.obj_arrays[objtype] + local i = 0 + return function() + i = i + 1 + if array[i] then return array[i] end + end +end + +function LinkTable:empty(objtype) + return #self.obj_arrays[objtype] == 0 +end + +--[[ + + Dumper: an object that can dump C initializers for several constructs. + Uses a LinkTable to resolve references when necessary. + +--]] + +local Dumper = {} +function Dumper:new(linktab) + local obj = {linktab = linktab} + setmetatable(obj, {__index = Dumper}) -- Inheritance + return obj +end + +-- Dumps a upb_tabval, eg: +-- UPB_TABVALUE_INIT(5) +function Dumper:_value(val, upbtype) + if type(val) == "nil" then + return "UPB_TABVALUE_EMPTY_INIT" + elseif type(val) == "number" then + -- Use upbtype to disambiguate what kind of number it is. + if upbtype == upbtable.CTYPE_INT32 then + return string.format("UPB_TABVALUE_INT_INIT(%d)", val) + else + -- TODO(haberman): add support for these so we can properly support + -- default values. + error("Unsupported number type " .. upbtype) + end + elseif type(val) == "string" then + return string.format('UPB_TABVALUE_PTR_INIT("%s")', val) + else + -- We take this as an object reference that has an entry in the link table. + return string.format("UPB_TABVALUE_PTR_INIT(%s)", self.linktab:addr(val)) + end +end + +-- Dumps a table key. +function Dumper:tabkey(key) + if type(key) == "nil" then + return "UPB_TABKEY_NONE" + elseif type(key) == "string" then + local len = #key + local len1 = c_escape(len % 256) + local len2 = c_escape(math.floor(len / 256) % 256) + local len3 = c_escape(math.floor(len / (256 * 256)) % 256) + local len4 = c_escape(math.floor(len / (256 * 256 * 256)) % 256) + return string.format('UPB_TABKEY_STR("%s", "%s", "%s", "%s", "%s")', + len1, len2, len3, len4, key) + else + return string.format("UPB_TABKEY_NUM(%d)", key) + end +end + +-- Dumps a table entry. +function Dumper:tabent(ent) + local key = self:tabkey(ent.key) + local val = self:_value(ent.value, ent.valtype) + local next = self.linktab:addr(ent.next) + return string.format(' {%s, %s, %s},\n', key, val, next) +end + +-- Dumps an inttable array entry. This is almost the same as value() above, +-- except that nil values have a special value to indicate "empty". +function Dumper:arrayval(val) + if val.val then + return string.format(" %s,\n", self:_value(val.val, val.valtype)) + else + return " UPB_TABVALUE_EMPTY_INIT,\n" + end +end + +-- Dumps an initializer for the given strtable/inttable (respectively). Its +-- entries must have previously been added to the linktable. +function Dumper:strtable(t) + -- UPB_STRTABLE_INIT(count, mask, type, size_lg2, entries) + return string.format( + "UPB_STRTABLE_INIT(%d, %d, %s, %d, %s)", + t.count, t.mask, const(t, "ctype", upbtable) , t.size_lg2, + self.linktab:addr(t.entries[1].ptr)) +end + +function Dumper:inttable(t) + local lt = assert(self.linktab) + -- UPB_INTTABLE_INIT(count, mask, type, size_lg2, ent, a, asize, acount) + local entries = "NULL" + if #t.entries > 0 then + entries = lt:addr(t.entries[1].ptr) + end + return string.format( + "UPB_INTTABLE_INIT(%d, %d, %s, %d, %s, %s, %d, %d)", + t.count, t.mask, const(t, "ctype", upbtable), t.size_lg2, entries, + lt:addr(t.array[1].ptr), t.array_size, t.array_count) +end + +-- A visitor for visiting all tables of a def. Used first to count entries +-- and later to dump them. +local function gettables(def) + if def:def_type() == upb.DEF_MSG then + return {int = upbtable.msgdef_itof(def), str = upbtable.msgdef_ntof(def)} + elseif def:def_type() == upb.DEF_ENUM then + return {int = upbtable.enumdef_iton(def), str = upbtable.enumdef_ntoi(def)} + end +end + +local function emit_file_warning(filedef, append) + append('/* This file was generated by upbc (the upb compiler) from the input\n') + append(' * file:\n') + append(' *\n') + append(' * %s\n', filedef:name()) + append(' *\n') + append(' * Do not edit -- your changes will be discarded when the file is\n') + append(' * regenerated. */\n\n') +end + +local function join(...) + return table.concat({...}, ".") +end + +local function split(str) + local ret = {} + for word in string.gmatch(str, "%w+") do + table.insert(ret, word) + end + return ret +end + +local function to_cident(...) + return string.gsub(join(...), "[%./]", "_") +end + +local function to_preproc(...) + return string.upper(to_cident(...)) +end + +-- Strips away last path element, ie: +-- foo.Bar.Baz -> foo.Bar +local function remove_name(name) + local package_end = 0 + for i=1,string.len(name) do + if string.byte(name, i) == string.byte(".", 1) then + package_end = i - 1 + end + end + return string.sub(name, 1, package_end) +end + +local function start_namespace(package, append) + local package_components = split(package) + for _, component in ipairs(package_components) do + append("namespace %s {\n", component) + end +end + +local function end_namespace(package, append) + local package_components = split(package) + for i=#package_components,1,-1 do + append("} /* namespace %s */\n", package_components[i]) + end +end + +local function well_known_type(m) + local type_map = {} + type_map["google.protobuf.Duration"] = "UPB_WELLKNOWN_DURATION" + type_map["google.protobuf.Timestamp"] = "UPB_WELLKNOWN_TIMESTAMP" + type_map["google.protobuf.Value"] = "UPB_WELLKNOWN_VALUE" + type_map["google.protobuf.ListValue"] = "UPB_WELLKNOWN_LISTVALUE" + type_map["google.protobuf.Struct"] = "UPB_WELLKNOWN_STRUCT" + type_map["google.protobuf.DoubleValue"] = "UPB_WELLKNOWN_DOUBLEVALUE" + type_map["google.protobuf.FloatValue"] = "UPB_WELLKNOWN_FLOATVALUE" + type_map["google.protobuf.Int64Value"] = "UPB_WELLKNOWN_INT64VALUE" + type_map["google.protobuf.UInt64Value"] = "UPB_WELLKNOWN_UINT64VALUE" + type_map["google.protobuf.Int32Value"] = "UPB_WELLKNOWN_INT32VALUE" + type_map["google.protobuf.UInt32Value"] = "UPB_WELLKNOWN_UINT32VALUE" + type_map["google.protobuf.BoolValue"] = "UPB_WELLKNOWN_BOOLVALUE" + type_map["google.protobuf.StringValue"] = "UPB_WELLKNOWN_STRINGVALUE" + type_map["google.protobuf.BytesValue"] = "UPB_WELLKNOWN_BYTESVALUE" + local t = type_map[m:full_name()] + if (t == nil) then + t = "UPB_WELLKNOWN_UNSPECIFIED" + end + return t +end + +--[[ + + Top-level, exported dumper functions + +--]] + +local function dump_defs_c(filedef, append) + local defs = {} + for def in filedef:defs(upb.DEF_ANY) do + defs[#defs + 1] = def + if (def:def_type() == upb.DEF_MSG) then + for field in def:fields() do + defs[#defs + 1] = field + end + end + end + + -- Sort all defs by (type, name). + -- This gives us a linear ordering that we can use to create offsets into + -- shared arrays like REFTABLES, hash table entries, and arrays. + table.sort(defs, function(a, b) + if a:def_type() ~= b:def_type() then + return a:def_type() < b:def_type() + else + return a:full_name() < b:full_name() end + end + ) + + -- Perform pre-pass to build the link table. + local linktab = LinkTable:new{ + [upb.DEF_MSG] = "msgs", + [upb.DEF_FIELD] = "fields", + [upb.DEF_ENUM] = "enums", + intentries = "intentries", + strentries = "strentries", + arrays = "arrays", + } + local reftable_count = 0 + + for _, def in ipairs(defs) do + assert(def:is_frozen(), "can only dump frozen defs.") + linktab:add(def:def_type(), def) + reftable_count = reftable_count + 2 + local tables = gettables(def) + if tables then + for _, e in ipairs(tables.str.entries) do + linktab:add("strentries", e.ptr, e) + end + for _, e in ipairs(tables.int.entries) do + linktab:add("intentries", e.ptr, e) + end + for _, e in ipairs(tables.int.array) do + linktab:add("arrays", e.ptr, e) + end + end + end + + -- Emit forward declarations. + emit_file_warning(filedef, append) + append('#include "upb/def.h"\n') + append('#include "upb/structdefs.int.h"\n\n') + append("static const upb_msgdef %s;\n", linktab:cdecl(upb.DEF_MSG)) + append("static const upb_fielddef %s;\n", linktab:cdecl(upb.DEF_FIELD)) + if not linktab:empty(upb.DEF_ENUM) then + append("static const upb_enumdef %s;\n", linktab:cdecl(upb.DEF_ENUM)) + end + append("static const upb_tabent %s;\n", linktab:cdecl("strentries")) + if not linktab:empty("intentries") then + append("static const upb_tabent %s;\n", linktab:cdecl("intentries")) + end + append("static const upb_tabval %s;\n", linktab:cdecl("arrays")) + append("\n") + append("#ifdef UPB_DEBUG_REFS\n") + append("static upb_inttable reftables[%d];\n", reftable_count) + append("#endif\n") + append("\n") + + -- Emit defs. + local dumper = Dumper:new(linktab) + + local reftable = 0 + + append("static const upb_msgdef %s = {\n", linktab:cdecl(upb.DEF_MSG)) + for m in linktab:objs(upb.DEF_MSG) do + local tables = gettables(m) + -- UPB_MSGDEF_INIT(name, selector_count, submsg_field_count, itof, ntof, + -- refs, ref2s) + append(' UPB_MSGDEF_INIT("%s", %d, %d, %s, %s, %s, %s, %s,' .. + ' &reftables[%d], &reftables[%d]),\n', + m:full_name(), + upbtable.msgdef_selector_count(m), + upbtable.msgdef_submsg_field_count(m), + dumper:inttable(tables.int), + dumper:strtable(tables.str), + boolstr(m:_map_entry()), + const(m, "syntax"), + well_known_type(m), + reftable, reftable + 1) + reftable = reftable + 2 + end + append("};\n\n") + + append("static const upb_fielddef %s = {\n", linktab:cdecl(upb.DEF_FIELD)) + for f in linktab:objs(upb.DEF_FIELD) do + local subdef = "NULL" + if f:has_subdef() then + subdef = string.format("(const upb_def*)(%s)", linktab:addr(f:subdef())) + end + local intfmt + if f:type() == upb.TYPE_UINT32 or + f:type() == upb.TYPE_INT32 or + f:type() == upb.TYPE_UINT64 or + f:type() == upb.TYPE_INT64 then + intfmt = const(f, "intfmt") + else + intfmt = "0" + end + -- UPB_FIELDDEF_INIT(label, type, intfmt, tagdelim, is_extension, lazy, + -- packed, name, num, msgdef, subdef, selector_base, + -- index, -- default_value) + append(' UPB_FIELDDEF_INIT(%s, %s, %s, %s, %s, %s, %s, "%s", %d, %s, ' .. + '%s, %d, %d, {0},' .. -- TODO: support default value + '&reftables[%d], &reftables[%d]),\n', + const(f, "label"), const(f, "type"), intfmt, + boolstr(f:istagdelim()), boolstr(f:is_extension()), + boolstr(f:lazy()), boolstr(f:packed()), f:name(), f:number(), + linktab:addr(f:containing_type()), subdef, + upbtable.fielddef_selector_base(f), f:index(), + reftable, reftable + 1 + ) + reftable = reftable + 2 + end + append("};\n\n") + + if not linktab:empty(upb.DEF_ENUM) then + append("static const upb_enumdef %s = {\n", linktab:cdecl(upb.DEF_ENUM)) + for e in linktab:objs(upb.DEF_ENUM) do + local tables = gettables(e) + -- UPB_ENUMDEF_INIT(name, ntoi, iton, defaultval) + append(' UPB_ENUMDEF_INIT("%s", %s, %s, %d, ' .. + '&reftables[%d], &reftables[%d]),\n', + e:full_name(), + dumper:strtable(tables.str), + dumper:inttable(tables.int), + --e:default()) + 0, + reftable, reftable + 1) + reftable = reftable + 2 + end + append("};\n\n") + end + + append("static const upb_tabent %s = {\n", linktab:cdecl("strentries")) + for ent in linktab:objs("strentries") do + append(dumper:tabent(ent)) + end + append("};\n\n"); + + if not linktab:empty("intentries") then + append("static const upb_tabent %s = {\n", linktab:cdecl("intentries")) + for ent in linktab:objs("intentries") do + append(dumper:tabent(ent)) + end + append("};\n\n"); + end + + append("static const upb_tabval %s = {\n", linktab:cdecl("arrays")) + for ent in linktab:objs("arrays") do + append(dumper:arrayval(ent)) + end + append("};\n\n"); + + append("#ifdef UPB_DEBUG_REFS\n") + append("static upb_inttable reftables[%d] = {\n", reftable_count) + for i = 1,reftable_count do + append(" UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),\n") + end + append("};\n") + append("#endif\n\n") + + append("static const upb_msgdef *refm(const upb_msgdef *m, const void *owner) {\n") + append(" upb_msgdef_ref(m, owner);\n") + append(" return m;\n") + append("}\n\n") + append("static const upb_enumdef *refe(const upb_enumdef *e, const void *owner) {\n") + append(" upb_enumdef_ref(e, owner);\n") + append(" return e;\n") + append("}\n\n") + + append("/* Public API. */\n") + + for m in linktab:objs(upb.DEF_MSG) do + append("const upb_msgdef *upbdefs_%s_get(const void *owner)" .. + " { return refm(%s, owner); }\n", + to_cident(m:full_name()), linktab:addr(m)) + end + + append("\n") + + for e in linktab:objs(upb.DEF_ENUM) do + append("const upb_enumdef *upbdefs_%s_get(const void *owner)" .. + " { return refe(%s, owner); }\n", + to_cident(e:full_name()), linktab:addr(e)) + end + + return linktab +end + +local function dump_defs_for_type(format, defs, append) + local sorted = sorted_defs(defs) + for _, def in ipairs(sorted) do + append(format, to_cident(def:full_name()), def:full_name()) + end + + append("\n") +end + +local function make_children_map(file) + -- Maps file:package() or msg:full_name() -> children. + local map = {} + for def in file:defs(upb.DEF_ANY) do + local container = remove_name(def:full_name()) + if not map[container] then + map[container] = {} + end + table.insert(map[container], def) + end + + -- Sort all the lists for a consistent ordering. + for name, children in pairs(map) do + table.sort(children, function(a, b) return a:name() < b:name() end) + end + + return map +end + +local print_classes + +local function print_message(def, map, indent, append) + append("\n") + append("%sclass %s : public ::upb::reffed_ptr {\n", + indent, def:name()) + append("%s public:\n", indent) + append("%s %s(const ::upb::MessageDef* m, const void *ref_donor = NULL)\n", + indent, def:name()) + append("%s : reffed_ptr(m, ref_donor) {\n", indent) + append("%s UPB_ASSERT(upbdefs_%s_is(m));\n", indent, to_cident(def:full_name())) + append("%s }\n", indent) + append("\n") + append("%s static %s get() {\n", indent, def:name()) + append("%s const ::upb::MessageDef* m = upbdefs_%s_get(&m);\n", indent, to_cident(def:full_name())) + append("%s return %s(m, &m);\n", indent, def:name()) + append("%s }\n", indent) + -- TODO(haberman): add fields + print_classes(def:full_name(), map, indent .. " ", append) + append("%s};\n", indent) +end + +local function print_enum(def, indent, append) + append("\n") + append("%sclass %s : public ::upb::reffed_ptr {\n", + indent, def:name()) + append("%s public:\n", indent) + append("%s %s(const ::upb::EnumDef* e, const void *ref_donor = NULL)\n", + indent, def:name()) + append("%s : reffed_ptr(e, ref_donor) {\n", indent) + append("%s UPB_ASSERT(upbdefs_%s_is(e));\n", indent, to_cident(def:full_name())) + append("%s }\n", indent) + append("%s static %s get() {\n", indent, def:name()) + append("%s const ::upb::EnumDef* e = upbdefs_%s_get(&e);\n", indent, to_cident(def:full_name())) + append("%s return %s(e, &e);\n", indent, def:name()) + append("%s }\n", indent) + append("%s};\n", indent) +end + +function print_classes(name, map, indent, append) + if not map[name] then + return + end + + for _, def in ipairs(map[name]) do + if def:def_type() == upb.DEF_MSG then + print_message(def, map, indent, append) + elseif def:def_type() == upb.DEF_ENUM then + print_enum(def, indent, append) + else + error("Unknown def type for " .. def:full_name()) + end + end +end + +local function dump_defs_h(file, append, linktab) + local basename_preproc = to_preproc(file:name()) + append("/* This file contains accessors for a set of compiled-in defs.\n") + append(" * Note that unlike Google's protobuf, it does *not* define\n") + append(" * generated classes or any other kind of data structure for\n") + append(" * actually storing protobufs. It only contains *defs* which\n") + append(" * let you reflect over a protobuf *schema*.\n") + append(" */\n") + emit_file_warning(file, append) + append('#ifndef %s_UPB_H_\n', basename_preproc) + append('#define %s_UPB_H_\n\n', basename_preproc) + append('#include "upb/def.h"\n\n') + append('UPB_BEGIN_EXTERN_C\n\n') + + -- Dump C enums for proto enums. + + append("/* MessageDefs: call these functions to get a ref to a msgdef. */\n") + dump_defs_for_type( + "const upb_msgdef *upbdefs_%s_get(const void *owner);\n", + file:defs(upb.DEF_MSG), append) + + append("/* EnumDefs: call these functions to get a ref to an enumdef. */\n") + dump_defs_for_type( + "const upb_enumdef *upbdefs_%s_get(const void *owner);\n", + file:defs(upb.DEF_ENUM), append) + + append("/* Functions to test whether this message is of a certain type. */\n") + dump_defs_for_type( + "UPB_INLINE bool upbdefs_%s_is(const upb_msgdef *m) {\n" .. + " return strcmp(upb_msgdef_fullname(m), \"%s\") == 0;\n}\n", + file:defs(upb.DEF_MSG), append) + + append("/* Functions to test whether this enum is of a certain type. */\n") + dump_defs_for_type( + "UPB_INLINE bool upbdefs_%s_is(const upb_enumdef *e) {\n" .. + " return strcmp(upb_enumdef_fullname(e), \"%s\") == 0;\n}\n", + file:defs(upb.DEF_ENUM), append) + + append("\n") + + -- fields + local fields = {} + + for f in linktab:objs(upb.DEF_FIELD) do + local symname = f:containing_type():full_name() .. "." .. f:name() + fields[#fields + 1] = {to_cident(symname), f} + end + + table.sort(fields, function(a, b) return a[1] < b[1] end) + + append("/* Functions to get a fielddef from a msgdef reference. */\n") + for _, field in ipairs(fields) do + local f = field[2] + local msg_cident = to_cident(f:containing_type():full_name()) + local field_cident = to_cident(f:name()) + append("UPB_INLINE const upb_fielddef *upbdefs_%s_f_%s(const upb_msgdef *m) {" .. + " UPB_ASSERT(upbdefs_%s_is(m));" .. + " return upb_msgdef_itof(m, %d); }\n", + msg_cident, field_cident, msg_cident, f:number()) + end + + append('\nUPB_END_EXTERN_C\n\n') + + -- C++ wrappers. + local children_map = make_children_map(file) + + append("#ifdef __cplusplus\n\n") + append("namespace upbdefs {\n") + start_namespace(file:package(), append) + print_classes(file:package(), children_map, "", append) + append("\n") + end_namespace(file:package(), append) + append("} /* namespace upbdefs */\n\n") + append("#endif /* __cplusplus */\n") + + append("\n") + append('#endif /* %s_UPB_H_ */\n', basename_preproc) +end + +function export.dump_defs(filedef, append_h, append_c) + local linktab = dump_defs_c(filedef, append_c) + dump_defs_h(filedef, append_h, linktab) +end + +return export diff --git a/upb/def.c b/upb/def.c index 2e53cf7a63..3fe1fe6c0d 100644 --- a/upb/def.c +++ b/upb/def.c @@ -272,6 +272,45 @@ static bool assign_msg_indices(upb_msgdef *m, upb_status *s) { return true; } +static void assign_msg_wellknowntype(upb_msgdef *m) { + const char *name = upb_msgdef_fullname(m); + if (name == NULL) { + m->well_known_type = UPB_WELLKNOWN_UNSPECIFIED; + return; + } + if (!strcmp(name, "google.protobuf.Duration")) { + m->well_known_type = UPB_WELLKNOWN_DURATION; + } else if (!strcmp(name, "google.protobuf.Timestamp")) { + m->well_known_type = UPB_WELLKNOWN_TIMESTAMP; + } else if (!strcmp(name, "google.protobuf.DoubleValue")) { + m->well_known_type = UPB_WELLKNOWN_DOUBLEVALUE; + } else if (!strcmp(name, "google.protobuf.FloatValue")) { + m->well_known_type = UPB_WELLKNOWN_FLOATVALUE; + } else if (!strcmp(name, "google.protobuf.Int64Value")) { + m->well_known_type = UPB_WELLKNOWN_INT64VALUE; + } else if (!strcmp(name, "google.protobuf.UInt64Value")) { + m->well_known_type = UPB_WELLKNOWN_UINT64VALUE; + } else if (!strcmp(name, "google.protobuf.Int32Value")) { + m->well_known_type = UPB_WELLKNOWN_INT32VALUE; + } else if (!strcmp(name, "google.protobuf.UInt32Value")) { + m->well_known_type = UPB_WELLKNOWN_UINT32VALUE; + } else if (!strcmp(name, "google.protobuf.BoolValue")) { + m->well_known_type = UPB_WELLKNOWN_BOOLVALUE; + } else if (!strcmp(name, "google.protobuf.StringValue")) { + m->well_known_type = UPB_WELLKNOWN_STRINGVALUE; + } else if (!strcmp(name, "google.protobuf.BytesValue")) { + m->well_known_type = UPB_WELLKNOWN_BYTESVALUE; + } else if (!strcmp(name, "google.protobuf.Value")) { + m->well_known_type = UPB_WELLKNOWN_VALUE; + } else if (!strcmp(name, "google.protobuf.ListValue")) { + m->well_known_type = UPB_WELLKNOWN_LISTVALUE; + } else if (!strcmp(name, "google.protobuf.Struct")) { + m->well_known_type = UPB_WELLKNOWN_STRUCT; + } else { + m->well_known_type = UPB_WELLKNOWN_UNSPECIFIED; + } +} + #if 0 bool _upb_def_validate(upb_def *const*defs, size_t n, upb_status *s) { size_t i; @@ -309,6 +348,8 @@ bool _upb_def_validate(upb_def *const*defs, size_t n, upb_status *s) { if (!assign_msg_indices(m, s)) { goto err; } + assign_msg_wellknowntype(m); + /* m->well_known_type = UPB_WELLKNOWN_UNSPECIFIED; */ } else if (e) { upb_inttable_compact(&e->iton); } @@ -755,12 +796,6 @@ bool upb_fielddef_checkdescriptortype(int32_t type) { /* upb_msgdef *****************************************************************/ -static const char *kDurationFullMessageName = "google.protobuf.Duration"; -static const char *kTimestampFullMessageName = "google.protobuf.Timestamp"; -static const char *kValueFullMessageName = "google.protobuf.Value"; -static const char *kListValueFullMessageName = "google.protobuf.ListValue"; -static const char *kStructFullMessageName = "google.protobuf.Struct"; - const char *upb_msgdef_fullname(const upb_msgdef *m) { return upb_def_fullname(upb_msgdef_upcast(m)); } @@ -927,24 +962,14 @@ bool upb_msgdef_mapentry(const upb_msgdef *m) { return m->map_entry; } -bool upb_msgdef_duration(const upb_msgdef *m) { - return strcmp(upb_msgdef_fullname(m), kDurationFullMessageName) == 0; -} - -bool upb_msgdef_timestamp(const upb_msgdef *m) { - return strcmp(upb_msgdef_fullname(m), kTimestampFullMessageName) == 0; -} - -bool upb_msgdef_value(const upb_msgdef *m) { - return strcmp(upb_msgdef_fullname(m), kValueFullMessageName) == 0; -} - -bool upb_msgdef_listvalue(const upb_msgdef *m) { - return strcmp(upb_msgdef_fullname(m), kListValueFullMessageName) == 0; +upb_wellknowntype_t upb_msgdef_wellknowntype(const upb_msgdef *m) { + return m->well_known_type; } -bool upb_msgdef_structvalue(const upb_msgdef *m) { - return strcmp(upb_msgdef_fullname(m), kStructFullMessageName) == 0; +bool upb_msgdef_isnumberwrapper(const upb_msgdef *m) { + upb_wellknowntype_t type = upb_msgdef_wellknowntype(m); + return type >= UPB_WELLKNOWN_DOUBLEVALUE && + type <= UPB_WELLKNOWN_UINT32VALUE; } void upb_msg_field_begin(upb_msg_field_iter *iter, const upb_msgdef *m) { diff --git a/upb/def.h b/upb/def.h index c229ca4340..a2958ad025 100644 --- a/upb/def.h +++ b/upb/def.h @@ -327,20 +327,12 @@ class upb::MessageDef { void setmapentry(bool map_entry); bool mapentry() const; - /* Is this message a duration? */ - bool duration() const; + /* Return the type of well known type message. UPB_WELLKNOWN_UNSPECIFIED for + * non-well-known message. */ + upb_wellknowntype_t wellknowntype() const; - /* Is this message a timestamp? */ - bool timestamp() const; - - /* Is this message a value? */ - bool value() const; - - /* Is this message a list value? */ - bool listvalue() const; - - /* Is this message a struct value? */ - bool structvalue() const; + /* Whether is a number wrapper. */ + bool isnumberwrapper() const; /* Iteration over fields. The order is undefined. */ class const_field_iterator @@ -414,11 +406,9 @@ const char *upb_msgdef_name(const upb_msgdef *m); int upb_msgdef_numoneofs(const upb_msgdef *m); upb_syntax_t upb_msgdef_syntax(const upb_msgdef *m); bool upb_msgdef_mapentry(const upb_msgdef *m); -bool upb_msgdef_duration(const upb_msgdef *m); -bool upb_msgdef_timestamp(const upb_msgdef *m); -bool upb_msgdef_value(const upb_msgdef *m); -bool upb_msgdef_listvalue(const upb_msgdef *m); -bool upb_msgdef_structvalue(const upb_msgdef *m); +upb_wellknowntype_t upb_msgdef_wellknowntype(const upb_msgdef *m); +bool upb_msgdef_isnumberwrapper(const upb_msgdef *m); +bool upb_msgdef_setsyntax(upb_msgdef *m, upb_syntax_t syntax); /* Internal-only. */ size_t upb_msgdef_selectorcount(const upb_msgdef *m); @@ -912,20 +902,11 @@ inline const OneofDef* MessageDef::FindOneofByName(const char* name, inline bool MessageDef::mapentry() const { return upb_msgdef_mapentry(this); } -inline bool MessageDef::duration() const { - return upb_msgdef_duration(this); -} -inline bool MessageDef::timestamp() const { - return upb_msgdef_timestamp(this); -} -inline bool MessageDef::value() const { - return upb_msgdef_value(this); -} -inline bool MessageDef::listvalue() const { - return upb_msgdef_listvalue(this); +inline upb_wellknowntype_t MessageDef::wellknowntype() const { + return upb_msgdef_wellknowntype(this); } -inline bool MessageDef::structvalue() const { - return upb_msgdef_structvalue(this); +inline bool MessageDef::isnumberwrapper() const { + return upb_msgdef_isnumberwrapper(this); } inline MessageDef::const_field_iterator MessageDef::field_begin() const { return const_field_iterator(this); diff --git a/upb/descriptor/descriptor.upbdefs.c b/upb/descriptor/descriptor.upbdefs.c new file mode 100644 index 0000000000..fa5bb3b1d4 --- /dev/null +++ b/upb/descriptor/descriptor.upbdefs.c @@ -0,0 +1,927 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * upb/descriptor/descriptor.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#include "upb/def.h" +#include "upb/structdefs.int.h" + +static const upb_msgdef msgs[22]; +static const upb_fielddef fields[107]; +static const upb_enumdef enums[5]; +static const upb_tabent strentries[236]; +static const upb_tabent intentries[18]; +static const upb_tabval arrays[187]; + +#ifdef UPB_DEBUG_REFS +static upb_inttable reftables[268]; +#endif + +static const upb_msgdef msgs[22] = { + UPB_MSGDEF_INIT("google.protobuf.DescriptorProto", 41, 8, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[0], 11, 10), UPB_STRTABLE_INIT(10, 15, UPB_CTYPE_PTR, 4, &strentries[0]), false, UPB_SYNTAX_PROTO2, UPB_WELLKNOWN_UNSPECIFIED, &reftables[0], &reftables[1]), + UPB_MSGDEF_INIT("google.protobuf.DescriptorProto.ExtensionRange", 5, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[11], 3, 2), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[16]), false, UPB_SYNTAX_PROTO2, UPB_WELLKNOWN_UNSPECIFIED, &reftables[2], &reftables[3]), + UPB_MSGDEF_INIT("google.protobuf.DescriptorProto.ReservedRange", 5, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[14], 3, 2), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[20]), false, UPB_SYNTAX_PROTO2, UPB_WELLKNOWN_UNSPECIFIED, &reftables[4], &reftables[5]), + UPB_MSGDEF_INIT("google.protobuf.EnumDescriptorProto", 12, 2, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[17], 4, 3), UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_PTR, 2, &strentries[24]), false, UPB_SYNTAX_PROTO2, UPB_WELLKNOWN_UNSPECIFIED, &reftables[6], &reftables[7]), + UPB_MSGDEF_INIT("google.protobuf.EnumOptions", 9, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[0], &arrays[21], 4, 2), UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_PTR, 2, &strentries[28]), false, UPB_SYNTAX_PROTO2, UPB_WELLKNOWN_UNSPECIFIED, &reftables[8], &reftables[9]), + UPB_MSGDEF_INIT("google.protobuf.EnumValueDescriptorProto", 9, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[25], 4, 3), UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_PTR, 2, &strentries[32]), false, UPB_SYNTAX_PROTO2, UPB_WELLKNOWN_UNSPECIFIED, &reftables[10], &reftables[11]), + UPB_MSGDEF_INIT("google.protobuf.EnumValueOptions", 8, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[2], &arrays[29], 2, 1), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[36]), false, UPB_SYNTAX_PROTO2, UPB_WELLKNOWN_UNSPECIFIED, &reftables[12], &reftables[13]), + UPB_MSGDEF_INIT("google.protobuf.FieldDescriptorProto", 24, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[31], 11, 10), UPB_STRTABLE_INIT(10, 15, UPB_CTYPE_PTR, 4, &strentries[40]), false, UPB_SYNTAX_PROTO2, UPB_WELLKNOWN_UNSPECIFIED, &reftables[14], &reftables[15]), + UPB_MSGDEF_INIT("google.protobuf.FieldOptions", 13, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[4], &arrays[42], 11, 6), UPB_STRTABLE_INIT(7, 15, UPB_CTYPE_PTR, 4, &strentries[56]), false, UPB_SYNTAX_PROTO2, UPB_WELLKNOWN_UNSPECIFIED, &reftables[16], &reftables[17]), + UPB_MSGDEF_INIT("google.protobuf.FileDescriptorProto", 43, 6, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[53], 13, 12), UPB_STRTABLE_INIT(12, 15, UPB_CTYPE_PTR, 4, &strentries[72]), false, UPB_SYNTAX_PROTO2, UPB_WELLKNOWN_UNSPECIFIED, &reftables[18], &reftables[19]), + UPB_MSGDEF_INIT("google.protobuf.FileDescriptorSet", 7, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[66], 2, 1), UPB_STRTABLE_INIT(1, 3, UPB_CTYPE_PTR, 2, &strentries[88]), false, UPB_SYNTAX_PROTO2, UPB_WELLKNOWN_UNSPECIFIED, &reftables[20], &reftables[21]), + UPB_MSGDEF_INIT("google.protobuf.FileOptions", 38, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[6], &arrays[68], 42, 17), UPB_STRTABLE_INIT(18, 31, UPB_CTYPE_PTR, 5, &strentries[92]), false, UPB_SYNTAX_PROTO2, UPB_WELLKNOWN_UNSPECIFIED, &reftables[22], &reftables[23]), + UPB_MSGDEF_INIT("google.protobuf.MessageOptions", 11, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[8], &arrays[110], 8, 4), UPB_STRTABLE_INIT(5, 7, UPB_CTYPE_PTR, 3, &strentries[124]), false, UPB_SYNTAX_PROTO2, UPB_WELLKNOWN_UNSPECIFIED, &reftables[24], &reftables[25]), + UPB_MSGDEF_INIT("google.protobuf.MethodDescriptorProto", 16, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[118], 7, 6), UPB_STRTABLE_INIT(6, 7, UPB_CTYPE_PTR, 3, &strentries[132]), false, UPB_SYNTAX_PROTO2, UPB_WELLKNOWN_UNSPECIFIED, &reftables[26], &reftables[27]), + UPB_MSGDEF_INIT("google.protobuf.MethodOptions", 8, 1, UPB_INTTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &intentries[10], &arrays[125], 1, 0), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[140]), false, UPB_SYNTAX_PROTO2, UPB_WELLKNOWN_UNSPECIFIED, &reftables[28], &reftables[29]), + UPB_MSGDEF_INIT("google.protobuf.OneofDescriptorProto", 6, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[126], 2, 1), UPB_STRTABLE_INIT(1, 3, UPB_CTYPE_PTR, 2, &strentries[144]), false, UPB_SYNTAX_PROTO2, UPB_WELLKNOWN_UNSPECIFIED, &reftables[30], &reftables[31]), + UPB_MSGDEF_INIT("google.protobuf.ServiceDescriptorProto", 12, 2, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[128], 4, 3), UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_PTR, 2, &strentries[148]), false, UPB_SYNTAX_PROTO2, UPB_WELLKNOWN_UNSPECIFIED, &reftables[32], &reftables[33]), + UPB_MSGDEF_INIT("google.protobuf.ServiceOptions", 8, 1, UPB_INTTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &intentries[14], &arrays[132], 1, 0), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[152]), false, UPB_SYNTAX_PROTO2, UPB_WELLKNOWN_UNSPECIFIED, &reftables[34], &reftables[35]), + UPB_MSGDEF_INIT("google.protobuf.SourceCodeInfo", 7, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[133], 2, 1), UPB_STRTABLE_INIT(1, 3, UPB_CTYPE_PTR, 2, &strentries[156]), false, UPB_SYNTAX_PROTO2, UPB_WELLKNOWN_UNSPECIFIED, &reftables[36], &reftables[37]), + UPB_MSGDEF_INIT("google.protobuf.SourceCodeInfo.Location", 20, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[135], 7, 5), UPB_STRTABLE_INIT(5, 7, UPB_CTYPE_PTR, 3, &strentries[160]), false, UPB_SYNTAX_PROTO2, UPB_WELLKNOWN_UNSPECIFIED, &reftables[38], &reftables[39]), + UPB_MSGDEF_INIT("google.protobuf.UninterpretedOption", 19, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[142], 9, 7), UPB_STRTABLE_INIT(7, 15, UPB_CTYPE_PTR, 4, &strentries[168]), false, UPB_SYNTAX_PROTO2, UPB_WELLKNOWN_UNSPECIFIED, &reftables[40], &reftables[41]), + UPB_MSGDEF_INIT("google.protobuf.UninterpretedOption.NamePart", 7, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[151], 3, 2), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[184]), false, UPB_SYNTAX_PROTO2, UPB_WELLKNOWN_UNSPECIFIED, &reftables[42], &reftables[43]), +}; + +static const upb_fielddef fields[107] = { + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "aggregate_value", 8, &msgs[20], NULL, 16, 6, {0},&reftables[44], &reftables[45]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "allow_alias", 2, &msgs[4], NULL, 7, 1, {0},&reftables[46], &reftables[47]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "cc_enable_arenas", 31, &msgs[11], NULL, 24, 12, {0},&reftables[48], &reftables[49]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "cc_generic_services", 16, &msgs[11], NULL, 18, 6, {0},&reftables[50], &reftables[51]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "client_streaming", 5, &msgs[13], NULL, 14, 4, {0},&reftables[52], &reftables[53]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "csharp_namespace", 37, &msgs[11], NULL, 28, 14, {0},&reftables[54], &reftables[55]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_ENUM, 0, false, false, false, false, "ctype", 1, &msgs[8], (const upb_def*)(&enums[2]), 7, 1, {0},&reftables[56], &reftables[57]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "default_value", 7, &msgs[7], NULL, 17, 7, {0},&reftables[58], &reftables[59]), + UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_STRING, 0, false, false, false, false, "dependency", 3, &msgs[9], NULL, 31, 8, {0},&reftables[60], &reftables[61]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "deprecated", 3, &msgs[8], NULL, 9, 3, {0},&reftables[62], &reftables[63]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "deprecated", 33, &msgs[14], NULL, 7, 1, {0},&reftables[64], &reftables[65]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "deprecated", 3, &msgs[12], NULL, 9, 3, {0},&reftables[66], &reftables[67]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "deprecated", 23, &msgs[11], NULL, 22, 10, {0},&reftables[68], &reftables[69]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "deprecated", 1, &msgs[6], NULL, 7, 1, {0},&reftables[70], &reftables[71]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "deprecated", 3, &msgs[4], NULL, 8, 2, {0},&reftables[72], &reftables[73]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "deprecated", 33, &msgs[17], NULL, 7, 1, {0},&reftables[74], &reftables[75]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_DOUBLE, 0, false, false, false, false, "double_value", 6, &msgs[20], NULL, 12, 4, {0},&reftables[76], &reftables[77]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "end", 2, &msgs[2], NULL, 4, 1, {0},&reftables[78], &reftables[79]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "end", 2, &msgs[1], NULL, 4, 1, {0},&reftables[80], &reftables[81]), + UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "enum_type", 5, &msgs[9], (const upb_def*)(&msgs[3]), 14, 1, {0},&reftables[82], &reftables[83]), + UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "enum_type", 4, &msgs[0], (const upb_def*)(&msgs[3]), 19, 2, {0},&reftables[84], &reftables[85]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "extendee", 2, &msgs[7], NULL, 8, 2, {0},&reftables[86], &reftables[87]), + UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "extension", 6, &msgs[0], (const upb_def*)(&msgs[7]), 25, 4, {0},&reftables[88], &reftables[89]), + UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "extension", 7, &msgs[9], (const upb_def*)(&msgs[7]), 20, 3, {0},&reftables[90], &reftables[91]), + UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "extension_range", 5, &msgs[0], (const upb_def*)(&msgs[1]), 22, 3, {0},&reftables[92], &reftables[93]), + UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "field", 2, &msgs[0], (const upb_def*)(&msgs[7]), 13, 0, {0},&reftables[94], &reftables[95]), + UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "file", 1, &msgs[10], (const upb_def*)(&msgs[9]), 6, 0, {0},&reftables[96], &reftables[97]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "go_package", 11, &msgs[11], NULL, 15, 5, {0},&reftables[98], &reftables[99]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "identifier_value", 3, &msgs[20], NULL, 7, 1, {0},&reftables[100], &reftables[101]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "input_type", 2, &msgs[13], NULL, 8, 2, {0},&reftables[102], &reftables[103]), + UPB_FIELDDEF_INIT(UPB_LABEL_REQUIRED, UPB_TYPE_BOOL, 0, false, false, false, false, "is_extension", 2, &msgs[21], NULL, 6, 1, {0},&reftables[104], &reftables[105]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "java_generate_equals_and_hash", 20, &msgs[11], NULL, 21, 9, {0},&reftables[106], &reftables[107]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "java_generic_services", 17, &msgs[11], NULL, 19, 7, {0},&reftables[108], &reftables[109]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "java_multiple_files", 10, &msgs[11], NULL, 14, 4, {0},&reftables[110], &reftables[111]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "java_outer_classname", 8, &msgs[11], NULL, 10, 2, {0},&reftables[112], &reftables[113]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "java_package", 1, &msgs[11], NULL, 7, 1, {0},&reftables[114], &reftables[115]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "java_string_check_utf8", 27, &msgs[11], NULL, 23, 11, {0},&reftables[116], &reftables[117]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "javanano_use_deprecated_package", 38, &msgs[11], NULL, 31, 15, {0},&reftables[118], &reftables[119]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "json_name", 10, &msgs[7], NULL, 21, 9, {0},&reftables[120], &reftables[121]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_ENUM, 0, false, false, false, false, "jstype", 6, &msgs[8], (const upb_def*)(&enums[3]), 11, 5, {0},&reftables[122], &reftables[123]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_ENUM, 0, false, false, false, false, "label", 4, &msgs[7], (const upb_def*)(&enums[0]), 12, 4, {0},&reftables[124], &reftables[125]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "lazy", 5, &msgs[8], NULL, 10, 4, {0},&reftables[126], &reftables[127]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "leading_comments", 3, &msgs[19], NULL, 9, 2, {0},&reftables[128], &reftables[129]), + UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_STRING, 0, false, false, false, false, "leading_detached_comments", 6, &msgs[19], NULL, 17, 4, {0},&reftables[130], &reftables[131]), + UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "location", 1, &msgs[18], (const upb_def*)(&msgs[19]), 6, 0, {0},&reftables[132], &reftables[133]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "map_entry", 7, &msgs[12], NULL, 10, 4, {0},&reftables[134], &reftables[135]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "message_set_wire_format", 1, &msgs[12], NULL, 7, 1, {0},&reftables[136], &reftables[137]), + UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "message_type", 4, &msgs[9], (const upb_def*)(&msgs[0]), 11, 0, {0},&reftables[138], &reftables[139]), + UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "method", 2, &msgs[16], (const upb_def*)(&msgs[13]), 7, 0, {0},&reftables[140], &reftables[141]), + UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "name", 2, &msgs[20], (const upb_def*)(&msgs[21]), 6, 0, {0},&reftables[142], &reftables[143]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[5], NULL, 5, 1, {0},&reftables[144], &reftables[145]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[9], NULL, 23, 6, {0},&reftables[146], &reftables[147]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[3], NULL, 9, 2, {0},&reftables[148], &reftables[149]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[16], NULL, 9, 2, {0},&reftables[150], &reftables[151]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[15], NULL, 3, 0, {0},&reftables[152], &reftables[153]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[13], NULL, 5, 1, {0},&reftables[154], &reftables[155]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[7], NULL, 5, 1, {0},&reftables[156], &reftables[157]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[0], NULL, 33, 8, {0},&reftables[158], &reftables[159]), + UPB_FIELDDEF_INIT(UPB_LABEL_REQUIRED, UPB_TYPE_STRING, 0, false, false, false, false, "name_part", 1, &msgs[21], NULL, 3, 0, {0},&reftables[160], &reftables[161]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT64, UPB_INTFMT_VARIABLE, false, false, false, false, "negative_int_value", 5, &msgs[20], NULL, 11, 3, {0},&reftables[162], &reftables[163]), + UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "nested_type", 3, &msgs[0], (const upb_def*)(&msgs[0]), 16, 1, {0},&reftables[164], &reftables[165]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "no_standard_descriptor_accessor", 2, &msgs[12], NULL, 8, 2, {0},&reftables[166], &reftables[167]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "number", 3, &msgs[7], NULL, 11, 3, {0},&reftables[168], &reftables[169]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "number", 2, &msgs[5], NULL, 8, 2, {0},&reftables[170], &reftables[171]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "objc_class_prefix", 36, &msgs[11], NULL, 25, 13, {0},&reftables[172], &reftables[173]), + UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "oneof_decl", 8, &msgs[0], (const upb_def*)(&msgs[15]), 29, 6, {0},&reftables[174], &reftables[175]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "oneof_index", 9, &msgs[7], NULL, 20, 8, {0},&reftables[176], &reftables[177]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_ENUM, 0, false, false, false, false, "optimize_for", 9, &msgs[11], (const upb_def*)(&enums[4]), 13, 3, {0},&reftables[178], &reftables[179]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 7, &msgs[0], (const upb_def*)(&msgs[12]), 26, 5, {0},&reftables[180], &reftables[181]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 8, &msgs[9], (const upb_def*)(&msgs[11]), 21, 4, {0},&reftables[182], &reftables[183]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 8, &msgs[7], (const upb_def*)(&msgs[8]), 4, 0, {0},&reftables[184], &reftables[185]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 4, &msgs[13], (const upb_def*)(&msgs[14]), 4, 0, {0},&reftables[186], &reftables[187]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 3, &msgs[16], (const upb_def*)(&msgs[17]), 8, 1, {0},&reftables[188], &reftables[189]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 3, &msgs[3], (const upb_def*)(&msgs[4]), 8, 1, {0},&reftables[190], &reftables[191]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 3, &msgs[5], (const upb_def*)(&msgs[6]), 4, 0, {0},&reftables[192], &reftables[193]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "output_type", 3, &msgs[13], NULL, 11, 3, {0},&reftables[194], &reftables[195]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "package", 2, &msgs[9], NULL, 26, 7, {0},&reftables[196], &reftables[197]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "packed", 2, &msgs[8], NULL, 8, 2, {0},&reftables[198], &reftables[199]), + UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, true, "path", 1, &msgs[19], NULL, 5, 0, {0},&reftables[200], &reftables[201]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "php_class_prefix", 40, &msgs[11], NULL, 32, 16, {0},&reftables[202], &reftables[203]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "php_namespace", 41, &msgs[11], NULL, 35, 17, {0},&reftables[204], &reftables[205]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_UINT64, UPB_INTFMT_VARIABLE, false, false, false, false, "positive_int_value", 4, &msgs[20], NULL, 10, 2, {0},&reftables[206], &reftables[207]), + UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "public_dependency", 10, &msgs[9], NULL, 36, 9, {0},&reftables[208], &reftables[209]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "py_generic_services", 18, &msgs[11], NULL, 20, 8, {0},&reftables[210], &reftables[211]), + UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_STRING, 0, false, false, false, false, "reserved_name", 10, &msgs[0], NULL, 38, 9, {0},&reftables[212], &reftables[213]), + UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "reserved_range", 9, &msgs[0], (const upb_def*)(&msgs[2]), 32, 7, {0},&reftables[214], &reftables[215]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "server_streaming", 6, &msgs[13], NULL, 15, 5, {0},&reftables[216], &reftables[217]), + UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "service", 6, &msgs[9], (const upb_def*)(&msgs[16]), 17, 2, {0},&reftables[218], &reftables[219]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "source_code_info", 9, &msgs[9], (const upb_def*)(&msgs[18]), 22, 5, {0},&reftables[220], &reftables[221]), + UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, true, "span", 2, &msgs[19], NULL, 8, 1, {0},&reftables[222], &reftables[223]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "start", 1, &msgs[2], NULL, 3, 0, {0},&reftables[224], &reftables[225]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "start", 1, &msgs[1], NULL, 3, 0, {0},&reftables[226], &reftables[227]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BYTES, 0, false, false, false, false, "string_value", 7, &msgs[20], NULL, 13, 5, {0},&reftables[228], &reftables[229]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "syntax", 12, &msgs[9], NULL, 40, 11, {0},&reftables[230], &reftables[231]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "trailing_comments", 4, &msgs[19], NULL, 12, 3, {0},&reftables[232], &reftables[233]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_ENUM, 0, false, false, false, false, "type", 5, &msgs[7], (const upb_def*)(&enums[1]), 13, 5, {0},&reftables[234], &reftables[235]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "type_name", 6, &msgs[7], NULL, 14, 6, {0},&reftables[236], &reftables[237]), + UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[12], (const upb_def*)(&msgs[20]), 6, 0, {0},&reftables[238], &reftables[239]), + UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[17], (const upb_def*)(&msgs[20]), 6, 0, {0},&reftables[240], &reftables[241]), + UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[11], (const upb_def*)(&msgs[20]), 6, 0, {0},&reftables[242], &reftables[243]), + UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[14], (const upb_def*)(&msgs[20]), 6, 0, {0},&reftables[244], &reftables[245]), + UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[8], (const upb_def*)(&msgs[20]), 6, 0, {0},&reftables[246], &reftables[247]), + UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[6], (const upb_def*)(&msgs[20]), 6, 0, {0},&reftables[248], &reftables[249]), + UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[4], (const upb_def*)(&msgs[20]), 6, 0, {0},&reftables[250], &reftables[251]), + UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "value", 2, &msgs[3], (const upb_def*)(&msgs[5]), 7, 0, {0},&reftables[252], &reftables[253]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "weak", 10, &msgs[8], NULL, 12, 6, {0},&reftables[254], &reftables[255]), + UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "weak_dependency", 11, &msgs[9], NULL, 39, 10, {0},&reftables[256], &reftables[257]), +}; + +static const upb_enumdef enums[5] = { + UPB_ENUMDEF_INIT("google.protobuf.FieldDescriptorProto.Label", UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_INT32, 2, &strentries[188]), UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_CSTR, 0, NULL, &arrays[154], 4, 3), 0, &reftables[258], &reftables[259]), + UPB_ENUMDEF_INIT("google.protobuf.FieldDescriptorProto.Type", UPB_STRTABLE_INIT(18, 31, UPB_CTYPE_INT32, 5, &strentries[192]), UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_CSTR, 0, NULL, &arrays[158], 19, 18), 0, &reftables[260], &reftables[261]), + UPB_ENUMDEF_INIT("google.protobuf.FieldOptions.CType", UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_INT32, 2, &strentries[224]), UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_CSTR, 0, NULL, &arrays[177], 3, 3), 0, &reftables[262], &reftables[263]), + UPB_ENUMDEF_INIT("google.protobuf.FieldOptions.JSType", UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_INT32, 2, &strentries[228]), UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_CSTR, 0, NULL, &arrays[180], 3, 3), 0, &reftables[264], &reftables[265]), + UPB_ENUMDEF_INIT("google.protobuf.FileOptions.OptimizeMode", UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_INT32, 2, &strentries[232]), UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_CSTR, 0, NULL, &arrays[183], 4, 3), 0, &reftables[266], &reftables[267]), +}; + +static const upb_tabent strentries[236] = { + {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "extension"), UPB_TABVALUE_PTR_INIT(&fields[22]), NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_STR("\015", "\000", "\000", "\000", "reserved_name"), UPB_TABVALUE_PTR_INIT(&fields[84]), NULL}, + {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[57]), NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_STR("\005", "\000", "\000", "\000", "field"), UPB_TABVALUE_PTR_INIT(&fields[25]), &strentries[12]}, + {UPB_TABKEY_STR("\017", "\000", "\000", "\000", "extension_range"), UPB_TABVALUE_PTR_INIT(&fields[24]), &strentries[14]}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_STR("\013", "\000", "\000", "\000", "nested_type"), UPB_TABVALUE_PTR_INIT(&fields[60]), NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_STR("\016", "\000", "\000", "\000", "reserved_range"), UPB_TABVALUE_PTR_INIT(&fields[85]), NULL}, + {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "options"), UPB_TABVALUE_PTR_INIT(&fields[68]), NULL}, + {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "oneof_decl"), UPB_TABVALUE_PTR_INIT(&fields[65]), NULL}, + {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "enum_type"), UPB_TABVALUE_PTR_INIT(&fields[20]), &strentries[13]}, + {UPB_TABKEY_STR("\005", "\000", "\000", "\000", "start"), UPB_TABVALUE_PTR_INIT(&fields[91]), NULL}, + {UPB_TABKEY_STR("\003", "\000", "\000", "\000", "end"), UPB_TABVALUE_PTR_INIT(&fields[18]), NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_STR("\005", "\000", "\000", "\000", "start"), UPB_TABVALUE_PTR_INIT(&fields[90]), NULL}, + {UPB_TABKEY_STR("\003", "\000", "\000", "\000", "end"), UPB_TABVALUE_PTR_INIT(&fields[17]), NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_STR("\005", "\000", "\000", "\000", "value"), UPB_TABVALUE_PTR_INIT(&fields[104]), NULL}, + {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "options"), UPB_TABVALUE_PTR_INIT(&fields[73]), NULL}, + {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[52]), &strentries[26]}, + {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "uninterpreted_option"), UPB_TABVALUE_PTR_INIT(&fields[103]), NULL}, + {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "deprecated"), UPB_TABVALUE_PTR_INIT(&fields[14]), NULL}, + {UPB_TABKEY_STR("\013", "\000", "\000", "\000", "allow_alias"), UPB_TABVALUE_PTR_INIT(&fields[1]), NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_STR("\006", "\000", "\000", "\000", "number"), UPB_TABVALUE_PTR_INIT(&fields[63]), NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "options"), UPB_TABVALUE_PTR_INIT(&fields[74]), NULL}, + {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[50]), &strentries[34]}, + {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "uninterpreted_option"), UPB_TABVALUE_PTR_INIT(&fields[102]), NULL}, + {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "deprecated"), UPB_TABVALUE_PTR_INIT(&fields[13]), NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_STR("\013", "\000", "\000", "\000", "oneof_index"), UPB_TABVALUE_PTR_INIT(&fields[66]), NULL}, + {UPB_TABKEY_STR("\005", "\000", "\000", "\000", "label"), UPB_TABVALUE_PTR_INIT(&fields[40]), NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[56]), NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_STR("\006", "\000", "\000", "\000", "number"), UPB_TABVALUE_PTR_INIT(&fields[62]), &strentries[53]}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_STR("\010", "\000", "\000", "\000", "extendee"), UPB_TABVALUE_PTR_INIT(&fields[21]), NULL}, + {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "type_name"), UPB_TABVALUE_PTR_INIT(&fields[96]), NULL}, + {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "json_name"), UPB_TABVALUE_PTR_INIT(&fields[38]), NULL}, + {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "type"), UPB_TABVALUE_PTR_INIT(&fields[95]), &strentries[50]}, + {UPB_TABKEY_STR("\015", "\000", "\000", "\000", "default_value"), UPB_TABVALUE_PTR_INIT(&fields[7]), NULL}, + {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "options"), UPB_TABVALUE_PTR_INIT(&fields[70]), NULL}, + {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "uninterpreted_option"), UPB_TABVALUE_PTR_INIT(&fields[101]), NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "weak"), UPB_TABVALUE_PTR_INIT(&fields[105]), NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_STR("\006", "\000", "\000", "\000", "packed"), UPB_TABVALUE_PTR_INIT(&fields[77]), NULL}, + {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "lazy"), UPB_TABVALUE_PTR_INIT(&fields[41]), NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_STR("\005", "\000", "\000", "\000", "ctype"), UPB_TABVALUE_PTR_INIT(&fields[6]), NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_STR("\006", "\000", "\000", "\000", "jstype"), UPB_TABVALUE_PTR_INIT(&fields[39]), NULL}, + {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "deprecated"), UPB_TABVALUE_PTR_INIT(&fields[9]), NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "extension"), UPB_TABVALUE_PTR_INIT(&fields[23]), NULL}, + {UPB_TABKEY_STR("\017", "\000", "\000", "\000", "weak_dependency"), UPB_TABVALUE_PTR_INIT(&fields[106]), NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[51]), NULL}, + {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "service"), UPB_TABVALUE_PTR_INIT(&fields[87]), NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_STR("\020", "\000", "\000", "\000", "source_code_info"), UPB_TABVALUE_PTR_INIT(&fields[88]), NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_STR("\006", "\000", "\000", "\000", "syntax"), UPB_TABVALUE_PTR_INIT(&fields[93]), NULL}, + {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "dependency"), UPB_TABVALUE_PTR_INIT(&fields[8]), NULL}, + {UPB_TABKEY_STR("\014", "\000", "\000", "\000", "message_type"), UPB_TABVALUE_PTR_INIT(&fields[47]), NULL}, + {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "package"), UPB_TABVALUE_PTR_INIT(&fields[76]), NULL}, + {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "options"), UPB_TABVALUE_PTR_INIT(&fields[69]), &strentries[86]}, + {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "enum_type"), UPB_TABVALUE_PTR_INIT(&fields[19]), NULL}, + {UPB_TABKEY_STR("\021", "\000", "\000", "\000", "public_dependency"), UPB_TABVALUE_PTR_INIT(&fields[82]), &strentries[85]}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "file"), UPB_TABVALUE_PTR_INIT(&fields[26]), NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_STR("\023", "\000", "\000", "\000", "cc_generic_services"), UPB_TABVALUE_PTR_INIT(&fields[3]), NULL}, + {UPB_TABKEY_STR("\020", "\000", "\000", "\000", "csharp_namespace"), UPB_TABVALUE_PTR_INIT(&fields[5]), &strentries[116]}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "go_package"), UPB_TABVALUE_PTR_INIT(&fields[27]), NULL}, + {UPB_TABKEY_STR("\014", "\000", "\000", "\000", "java_package"), UPB_TABVALUE_PTR_INIT(&fields[35]), &strentries[120]}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "java_outer_classname"), UPB_TABVALUE_PTR_INIT(&fields[34]), NULL}, + {UPB_TABKEY_STR("\015", "\000", "\000", "\000", "php_namespace"), UPB_TABVALUE_PTR_INIT(&fields[80]), &strentries[113]}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_STR("\023", "\000", "\000", "\000", "java_multiple_files"), UPB_TABVALUE_PTR_INIT(&fields[33]), &strentries[117]}, + {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "uninterpreted_option"), UPB_TABVALUE_PTR_INIT(&fields[99]), NULL}, + {UPB_TABKEY_STR("\025", "\000", "\000", "\000", "java_generic_services"), UPB_TABVALUE_PTR_INIT(&fields[32]), &strentries[118]}, + {UPB_TABKEY_STR("\035", "\000", "\000", "\000", "java_generate_equals_and_hash"), UPB_TABVALUE_PTR_INIT(&fields[31]), NULL}, + {UPB_TABKEY_STR("\020", "\000", "\000", "\000", "php_class_prefix"), UPB_TABVALUE_PTR_INIT(&fields[79]), NULL}, + {UPB_TABKEY_STR("\037", "\000", "\000", "\000", "javanano_use_deprecated_package"), UPB_TABVALUE_PTR_INIT(&fields[37]), &strentries[123]}, + {UPB_TABKEY_STR("\023", "\000", "\000", "\000", "py_generic_services"), UPB_TABVALUE_PTR_INIT(&fields[83]), NULL}, + {UPB_TABKEY_STR("\014", "\000", "\000", "\000", "optimize_for"), UPB_TABVALUE_PTR_INIT(&fields[67]), NULL}, + {UPB_TABKEY_STR("\026", "\000", "\000", "\000", "java_string_check_utf8"), UPB_TABVALUE_PTR_INIT(&fields[36]), NULL}, + {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "deprecated"), UPB_TABVALUE_PTR_INIT(&fields[12]), &strentries[119]}, + {UPB_TABKEY_STR("\021", "\000", "\000", "\000", "objc_class_prefix"), UPB_TABVALUE_PTR_INIT(&fields[64]), NULL}, + {UPB_TABKEY_STR("\020", "\000", "\000", "\000", "cc_enable_arenas"), UPB_TABVALUE_PTR_INIT(&fields[2]), NULL}, + {UPB_TABKEY_STR("\027", "\000", "\000", "\000", "message_set_wire_format"), UPB_TABVALUE_PTR_INIT(&fields[46]), &strentries[128]}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "uninterpreted_option"), UPB_TABVALUE_PTR_INIT(&fields[97]), NULL}, + {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "deprecated"), UPB_TABVALUE_PTR_INIT(&fields[11]), NULL}, + {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "map_entry"), UPB_TABVALUE_PTR_INIT(&fields[45]), NULL}, + {UPB_TABKEY_STR("\037", "\000", "\000", "\000", "no_standard_descriptor_accessor"), UPB_TABVALUE_PTR_INIT(&fields[61]), NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_STR("\020", "\000", "\000", "\000", "client_streaming"), UPB_TABVALUE_PTR_INIT(&fields[4]), NULL}, + {UPB_TABKEY_STR("\020", "\000", "\000", "\000", "server_streaming"), UPB_TABVALUE_PTR_INIT(&fields[86]), NULL}, + {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[55]), NULL}, + {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "input_type"), UPB_TABVALUE_PTR_INIT(&fields[29]), NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_STR("\013", "\000", "\000", "\000", "output_type"), UPB_TABVALUE_PTR_INIT(&fields[75]), NULL}, + {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "options"), UPB_TABVALUE_PTR_INIT(&fields[71]), NULL}, + {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "uninterpreted_option"), UPB_TABVALUE_PTR_INIT(&fields[100]), NULL}, + {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "deprecated"), UPB_TABVALUE_PTR_INIT(&fields[10]), NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[54]), NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "options"), UPB_TABVALUE_PTR_INIT(&fields[72]), &strentries[150]}, + {UPB_TABKEY_STR("\006", "\000", "\000", "\000", "method"), UPB_TABVALUE_PTR_INIT(&fields[48]), NULL}, + {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[53]), &strentries[149]}, + {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "uninterpreted_option"), UPB_TABVALUE_PTR_INIT(&fields[98]), NULL}, + {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "deprecated"), UPB_TABVALUE_PTR_INIT(&fields[15]), NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_STR("\010", "\000", "\000", "\000", "location"), UPB_TABVALUE_PTR_INIT(&fields[44]), NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "span"), UPB_TABVALUE_PTR_INIT(&fields[89]), &strentries[167]}, + {UPB_TABKEY_STR("\031", "\000", "\000", "\000", "leading_detached_comments"), UPB_TABVALUE_PTR_INIT(&fields[43]), &strentries[165]}, + {UPB_TABKEY_STR("\021", "\000", "\000", "\000", "trailing_comments"), UPB_TABVALUE_PTR_INIT(&fields[94]), NULL}, + {UPB_TABKEY_STR("\020", "\000", "\000", "\000", "leading_comments"), UPB_TABVALUE_PTR_INIT(&fields[42]), &strentries[164]}, + {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "path"), UPB_TABVALUE_PTR_INIT(&fields[78]), NULL}, + {UPB_TABKEY_STR("\014", "\000", "\000", "\000", "double_value"), UPB_TABVALUE_PTR_INIT(&fields[16]), NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[49]), NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_STR("\022", "\000", "\000", "\000", "negative_int_value"), UPB_TABVALUE_PTR_INIT(&fields[59]), NULL}, + {UPB_TABKEY_STR("\017", "\000", "\000", "\000", "aggregate_value"), UPB_TABVALUE_PTR_INIT(&fields[0]), NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_STR("\022", "\000", "\000", "\000", "positive_int_value"), UPB_TABVALUE_PTR_INIT(&fields[81]), NULL}, + {UPB_TABKEY_STR("\020", "\000", "\000", "\000", "identifier_value"), UPB_TABVALUE_PTR_INIT(&fields[28]), NULL}, + {UPB_TABKEY_STR("\014", "\000", "\000", "\000", "string_value"), UPB_TABVALUE_PTR_INIT(&fields[92]), &strentries[182]}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_STR("\014", "\000", "\000", "\000", "is_extension"), UPB_TABVALUE_PTR_INIT(&fields[30]), NULL}, + {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "name_part"), UPB_TABVALUE_PTR_INIT(&fields[58]), NULL}, + {UPB_TABKEY_STR("\016", "\000", "\000", "\000", "LABEL_REQUIRED"), UPB_TABVALUE_INT_INIT(2), &strentries[190]}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_STR("\016", "\000", "\000", "\000", "LABEL_REPEATED"), UPB_TABVALUE_INT_INIT(3), NULL}, + {UPB_TABKEY_STR("\016", "\000", "\000", "\000", "LABEL_OPTIONAL"), UPB_TABVALUE_INT_INIT(1), NULL}, + {UPB_TABKEY_STR("\014", "\000", "\000", "\000", "TYPE_FIXED64"), UPB_TABVALUE_INT_INIT(6), NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_STR("\013", "\000", "\000", "\000", "TYPE_STRING"), UPB_TABVALUE_INT_INIT(9), NULL}, + {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "TYPE_FLOAT"), UPB_TABVALUE_INT_INIT(2), &strentries[221]}, + {UPB_TABKEY_STR("\013", "\000", "\000", "\000", "TYPE_DOUBLE"), UPB_TABVALUE_INT_INIT(1), NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "TYPE_INT32"), UPB_TABVALUE_INT_INIT(5), NULL}, + {UPB_TABKEY_STR("\015", "\000", "\000", "\000", "TYPE_SFIXED32"), UPB_TABVALUE_INT_INIT(15), NULL}, + {UPB_TABKEY_STR("\014", "\000", "\000", "\000", "TYPE_FIXED32"), UPB_TABVALUE_INT_INIT(7), NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_STR("\014", "\000", "\000", "\000", "TYPE_MESSAGE"), UPB_TABVALUE_INT_INIT(11), &strentries[222]}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "TYPE_INT64"), UPB_TABVALUE_INT_INIT(3), &strentries[219]}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "TYPE_ENUM"), UPB_TABVALUE_INT_INIT(14), NULL}, + {UPB_TABKEY_STR("\013", "\000", "\000", "\000", "TYPE_UINT32"), UPB_TABVALUE_INT_INIT(13), NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_STR("\013", "\000", "\000", "\000", "TYPE_UINT64"), UPB_TABVALUE_INT_INIT(4), &strentries[218]}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_STR("\015", "\000", "\000", "\000", "TYPE_SFIXED64"), UPB_TABVALUE_INT_INIT(16), NULL}, + {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "TYPE_BYTES"), UPB_TABVALUE_INT_INIT(12), NULL}, + {UPB_TABKEY_STR("\013", "\000", "\000", "\000", "TYPE_SINT64"), UPB_TABVALUE_INT_INIT(18), NULL}, + {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "TYPE_BOOL"), UPB_TABVALUE_INT_INIT(8), NULL}, + {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "TYPE_GROUP"), UPB_TABVALUE_INT_INIT(10), NULL}, + {UPB_TABKEY_STR("\013", "\000", "\000", "\000", "TYPE_SINT32"), UPB_TABVALUE_INT_INIT(17), NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "CORD"), UPB_TABVALUE_INT_INIT(1), NULL}, + {UPB_TABKEY_STR("\006", "\000", "\000", "\000", "STRING"), UPB_TABVALUE_INT_INIT(0), &strentries[225]}, + {UPB_TABKEY_STR("\014", "\000", "\000", "\000", "STRING_PIECE"), UPB_TABVALUE_INT_INIT(2), NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "JS_NORMAL"), UPB_TABVALUE_INT_INIT(0), NULL}, + {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "JS_NUMBER"), UPB_TABVALUE_INT_INIT(2), NULL}, + {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "JS_STRING"), UPB_TABVALUE_INT_INIT(1), NULL}, + {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "CODE_SIZE"), UPB_TABVALUE_INT_INIT(2), NULL}, + {UPB_TABKEY_STR("\005", "\000", "\000", "\000", "SPEED"), UPB_TABVALUE_INT_INIT(1), &strentries[235]}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_STR("\014", "\000", "\000", "\000", "LITE_RUNTIME"), UPB_TABVALUE_INT_INIT(3), NULL}, +}; + +static const upb_tabent intentries[18] = { + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_NUM(999), UPB_TABVALUE_PTR_INIT(&fields[103]), NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_NUM(999), UPB_TABVALUE_PTR_INIT(&fields[102]), NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_NUM(999), UPB_TABVALUE_PTR_INIT(&fields[101]), NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_NUM(999), UPB_TABVALUE_PTR_INIT(&fields[99]), NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_NUM(999), UPB_TABVALUE_PTR_INIT(&fields[97]), NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_NUM(33), UPB_TABVALUE_PTR_INIT(&fields[10]), NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_NUM(999), UPB_TABVALUE_PTR_INIT(&fields[100]), NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_NUM(33), UPB_TABVALUE_PTR_INIT(&fields[15]), NULL}, + {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_NUM(999), UPB_TABVALUE_PTR_INIT(&fields[98]), NULL}, +}; + +static const upb_tabval arrays[187] = { + UPB_TABVALUE_EMPTY_INIT, + UPB_TABVALUE_PTR_INIT(&fields[57]), + UPB_TABVALUE_PTR_INIT(&fields[25]), + UPB_TABVALUE_PTR_INIT(&fields[60]), + UPB_TABVALUE_PTR_INIT(&fields[20]), + UPB_TABVALUE_PTR_INIT(&fields[24]), + UPB_TABVALUE_PTR_INIT(&fields[22]), + UPB_TABVALUE_PTR_INIT(&fields[68]), + UPB_TABVALUE_PTR_INIT(&fields[65]), + UPB_TABVALUE_PTR_INIT(&fields[85]), + UPB_TABVALUE_PTR_INIT(&fields[84]), + UPB_TABVALUE_EMPTY_INIT, + UPB_TABVALUE_PTR_INIT(&fields[91]), + UPB_TABVALUE_PTR_INIT(&fields[18]), + UPB_TABVALUE_EMPTY_INIT, + UPB_TABVALUE_PTR_INIT(&fields[90]), + UPB_TABVALUE_PTR_INIT(&fields[17]), + UPB_TABVALUE_EMPTY_INIT, + UPB_TABVALUE_PTR_INIT(&fields[52]), + UPB_TABVALUE_PTR_INIT(&fields[104]), + UPB_TABVALUE_PTR_INIT(&fields[73]), + UPB_TABVALUE_EMPTY_INIT, + UPB_TABVALUE_EMPTY_INIT, + UPB_TABVALUE_PTR_INIT(&fields[1]), + UPB_TABVALUE_PTR_INIT(&fields[14]), + UPB_TABVALUE_EMPTY_INIT, + UPB_TABVALUE_PTR_INIT(&fields[50]), + UPB_TABVALUE_PTR_INIT(&fields[63]), + UPB_TABVALUE_PTR_INIT(&fields[74]), + UPB_TABVALUE_EMPTY_INIT, + UPB_TABVALUE_PTR_INIT(&fields[13]), + UPB_TABVALUE_EMPTY_INIT, + UPB_TABVALUE_PTR_INIT(&fields[56]), + UPB_TABVALUE_PTR_INIT(&fields[21]), + UPB_TABVALUE_PTR_INIT(&fields[62]), + UPB_TABVALUE_PTR_INIT(&fields[40]), + UPB_TABVALUE_PTR_INIT(&fields[95]), + UPB_TABVALUE_PTR_INIT(&fields[96]), + UPB_TABVALUE_PTR_INIT(&fields[7]), + UPB_TABVALUE_PTR_INIT(&fields[70]), + UPB_TABVALUE_PTR_INIT(&fields[66]), + UPB_TABVALUE_PTR_INIT(&fields[38]), + UPB_TABVALUE_EMPTY_INIT, + UPB_TABVALUE_PTR_INIT(&fields[6]), + UPB_TABVALUE_PTR_INIT(&fields[77]), + UPB_TABVALUE_PTR_INIT(&fields[9]), + UPB_TABVALUE_EMPTY_INIT, + UPB_TABVALUE_PTR_INIT(&fields[41]), + UPB_TABVALUE_PTR_INIT(&fields[39]), + UPB_TABVALUE_EMPTY_INIT, + UPB_TABVALUE_EMPTY_INIT, + UPB_TABVALUE_EMPTY_INIT, + UPB_TABVALUE_PTR_INIT(&fields[105]), + UPB_TABVALUE_EMPTY_INIT, + UPB_TABVALUE_PTR_INIT(&fields[51]), + UPB_TABVALUE_PTR_INIT(&fields[76]), + UPB_TABVALUE_PTR_INIT(&fields[8]), + UPB_TABVALUE_PTR_INIT(&fields[47]), + UPB_TABVALUE_PTR_INIT(&fields[19]), + UPB_TABVALUE_PTR_INIT(&fields[87]), + UPB_TABVALUE_PTR_INIT(&fields[23]), + UPB_TABVALUE_PTR_INIT(&fields[69]), + UPB_TABVALUE_PTR_INIT(&fields[88]), + UPB_TABVALUE_PTR_INIT(&fields[82]), + UPB_TABVALUE_PTR_INIT(&fields[106]), + UPB_TABVALUE_PTR_INIT(&fields[93]), + UPB_TABVALUE_EMPTY_INIT, + UPB_TABVALUE_PTR_INIT(&fields[26]), + UPB_TABVALUE_EMPTY_INIT, + UPB_TABVALUE_PTR_INIT(&fields[35]), + UPB_TABVALUE_EMPTY_INIT, + UPB_TABVALUE_EMPTY_INIT, + UPB_TABVALUE_EMPTY_INIT, + UPB_TABVALUE_EMPTY_INIT, + UPB_TABVALUE_EMPTY_INIT, + UPB_TABVALUE_EMPTY_INIT, + UPB_TABVALUE_PTR_INIT(&fields[34]), + UPB_TABVALUE_PTR_INIT(&fields[67]), + UPB_TABVALUE_PTR_INIT(&fields[33]), + UPB_TABVALUE_PTR_INIT(&fields[27]), + UPB_TABVALUE_EMPTY_INIT, + UPB_TABVALUE_EMPTY_INIT, + UPB_TABVALUE_EMPTY_INIT, + UPB_TABVALUE_EMPTY_INIT, + UPB_TABVALUE_PTR_INIT(&fields[3]), + UPB_TABVALUE_PTR_INIT(&fields[32]), + UPB_TABVALUE_PTR_INIT(&fields[83]), + UPB_TABVALUE_EMPTY_INIT, + UPB_TABVALUE_PTR_INIT(&fields[31]), + UPB_TABVALUE_EMPTY_INIT, + UPB_TABVALUE_EMPTY_INIT, + UPB_TABVALUE_PTR_INIT(&fields[12]), + UPB_TABVALUE_EMPTY_INIT, + UPB_TABVALUE_EMPTY_INIT, + UPB_TABVALUE_EMPTY_INIT, + UPB_TABVALUE_PTR_INIT(&fields[36]), + UPB_TABVALUE_EMPTY_INIT, + UPB_TABVALUE_EMPTY_INIT, + UPB_TABVALUE_EMPTY_INIT, + UPB_TABVALUE_PTR_INIT(&fields[2]), + UPB_TABVALUE_EMPTY_INIT, + UPB_TABVALUE_EMPTY_INIT, + UPB_TABVALUE_EMPTY_INIT, + UPB_TABVALUE_EMPTY_INIT, + UPB_TABVALUE_PTR_INIT(&fields[64]), + UPB_TABVALUE_PTR_INIT(&fields[5]), + UPB_TABVALUE_PTR_INIT(&fields[37]), + UPB_TABVALUE_EMPTY_INIT, + UPB_TABVALUE_PTR_INIT(&fields[79]), + UPB_TABVALUE_PTR_INIT(&fields[80]), + UPB_TABVALUE_EMPTY_INIT, + UPB_TABVALUE_PTR_INIT(&fields[46]), + UPB_TABVALUE_PTR_INIT(&fields[61]), + UPB_TABVALUE_PTR_INIT(&fields[11]), + UPB_TABVALUE_EMPTY_INIT, + UPB_TABVALUE_EMPTY_INIT, + UPB_TABVALUE_EMPTY_INIT, + UPB_TABVALUE_PTR_INIT(&fields[45]), + UPB_TABVALUE_EMPTY_INIT, + UPB_TABVALUE_PTR_INIT(&fields[55]), + UPB_TABVALUE_PTR_INIT(&fields[29]), + UPB_TABVALUE_PTR_INIT(&fields[75]), + UPB_TABVALUE_PTR_INIT(&fields[71]), + UPB_TABVALUE_PTR_INIT(&fields[4]), + UPB_TABVALUE_PTR_INIT(&fields[86]), + UPB_TABVALUE_EMPTY_INIT, + UPB_TABVALUE_EMPTY_INIT, + UPB_TABVALUE_PTR_INIT(&fields[54]), + UPB_TABVALUE_EMPTY_INIT, + UPB_TABVALUE_PTR_INIT(&fields[53]), + UPB_TABVALUE_PTR_INIT(&fields[48]), + UPB_TABVALUE_PTR_INIT(&fields[72]), + UPB_TABVALUE_EMPTY_INIT, + UPB_TABVALUE_EMPTY_INIT, + UPB_TABVALUE_PTR_INIT(&fields[44]), + UPB_TABVALUE_EMPTY_INIT, + UPB_TABVALUE_PTR_INIT(&fields[78]), + UPB_TABVALUE_PTR_INIT(&fields[89]), + UPB_TABVALUE_PTR_INIT(&fields[42]), + UPB_TABVALUE_PTR_INIT(&fields[94]), + UPB_TABVALUE_EMPTY_INIT, + UPB_TABVALUE_PTR_INIT(&fields[43]), + UPB_TABVALUE_EMPTY_INIT, + UPB_TABVALUE_EMPTY_INIT, + UPB_TABVALUE_PTR_INIT(&fields[49]), + UPB_TABVALUE_PTR_INIT(&fields[28]), + UPB_TABVALUE_PTR_INIT(&fields[81]), + UPB_TABVALUE_PTR_INIT(&fields[59]), + UPB_TABVALUE_PTR_INIT(&fields[16]), + UPB_TABVALUE_PTR_INIT(&fields[92]), + UPB_TABVALUE_PTR_INIT(&fields[0]), + UPB_TABVALUE_EMPTY_INIT, + UPB_TABVALUE_PTR_INIT(&fields[58]), + UPB_TABVALUE_PTR_INIT(&fields[30]), + UPB_TABVALUE_EMPTY_INIT, + UPB_TABVALUE_PTR_INIT("LABEL_OPTIONAL"), + UPB_TABVALUE_PTR_INIT("LABEL_REQUIRED"), + UPB_TABVALUE_PTR_INIT("LABEL_REPEATED"), + UPB_TABVALUE_EMPTY_INIT, + UPB_TABVALUE_PTR_INIT("TYPE_DOUBLE"), + UPB_TABVALUE_PTR_INIT("TYPE_FLOAT"), + UPB_TABVALUE_PTR_INIT("TYPE_INT64"), + UPB_TABVALUE_PTR_INIT("TYPE_UINT64"), + UPB_TABVALUE_PTR_INIT("TYPE_INT32"), + UPB_TABVALUE_PTR_INIT("TYPE_FIXED64"), + UPB_TABVALUE_PTR_INIT("TYPE_FIXED32"), + UPB_TABVALUE_PTR_INIT("TYPE_BOOL"), + UPB_TABVALUE_PTR_INIT("TYPE_STRING"), + UPB_TABVALUE_PTR_INIT("TYPE_GROUP"), + UPB_TABVALUE_PTR_INIT("TYPE_MESSAGE"), + UPB_TABVALUE_PTR_INIT("TYPE_BYTES"), + UPB_TABVALUE_PTR_INIT("TYPE_UINT32"), + UPB_TABVALUE_PTR_INIT("TYPE_ENUM"), + UPB_TABVALUE_PTR_INIT("TYPE_SFIXED32"), + UPB_TABVALUE_PTR_INIT("TYPE_SFIXED64"), + UPB_TABVALUE_PTR_INIT("TYPE_SINT32"), + UPB_TABVALUE_PTR_INIT("TYPE_SINT64"), + UPB_TABVALUE_PTR_INIT("STRING"), + UPB_TABVALUE_PTR_INIT("CORD"), + UPB_TABVALUE_PTR_INIT("STRING_PIECE"), + UPB_TABVALUE_PTR_INIT("JS_NORMAL"), + UPB_TABVALUE_PTR_INIT("JS_STRING"), + UPB_TABVALUE_PTR_INIT("JS_NUMBER"), + UPB_TABVALUE_EMPTY_INIT, + UPB_TABVALUE_PTR_INIT("SPEED"), + UPB_TABVALUE_PTR_INIT("CODE_SIZE"), + UPB_TABVALUE_PTR_INIT("LITE_RUNTIME"), +}; + +#ifdef UPB_DEBUG_REFS +static upb_inttable reftables[268] = { + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), +}; +#endif + +static const upb_msgdef *refm(const upb_msgdef *m, const void *owner) { + upb_msgdef_ref(m, owner); + return m; +} + +static const upb_enumdef *refe(const upb_enumdef *e, const void *owner) { + upb_enumdef_ref(e, owner); + return e; +} + +/* Public API. */ +const upb_msgdef *upbdefs_google_protobuf_DescriptorProto_get(const void *owner) { return refm(&msgs[0], owner); } +const upb_msgdef *upbdefs_google_protobuf_DescriptorProto_ExtensionRange_get(const void *owner) { return refm(&msgs[1], owner); } +const upb_msgdef *upbdefs_google_protobuf_DescriptorProto_ReservedRange_get(const void *owner) { return refm(&msgs[2], owner); } +const upb_msgdef *upbdefs_google_protobuf_EnumDescriptorProto_get(const void *owner) { return refm(&msgs[3], owner); } +const upb_msgdef *upbdefs_google_protobuf_EnumOptions_get(const void *owner) { return refm(&msgs[4], owner); } +const upb_msgdef *upbdefs_google_protobuf_EnumValueDescriptorProto_get(const void *owner) { return refm(&msgs[5], owner); } +const upb_msgdef *upbdefs_google_protobuf_EnumValueOptions_get(const void *owner) { return refm(&msgs[6], owner); } +const upb_msgdef *upbdefs_google_protobuf_FieldDescriptorProto_get(const void *owner) { return refm(&msgs[7], owner); } +const upb_msgdef *upbdefs_google_protobuf_FieldOptions_get(const void *owner) { return refm(&msgs[8], owner); } +const upb_msgdef *upbdefs_google_protobuf_FileDescriptorProto_get(const void *owner) { return refm(&msgs[9], owner); } +const upb_msgdef *upbdefs_google_protobuf_FileDescriptorSet_get(const void *owner) { return refm(&msgs[10], owner); } +const upb_msgdef *upbdefs_google_protobuf_FileOptions_get(const void *owner) { return refm(&msgs[11], owner); } +const upb_msgdef *upbdefs_google_protobuf_MessageOptions_get(const void *owner) { return refm(&msgs[12], owner); } +const upb_msgdef *upbdefs_google_protobuf_MethodDescriptorProto_get(const void *owner) { return refm(&msgs[13], owner); } +const upb_msgdef *upbdefs_google_protobuf_MethodOptions_get(const void *owner) { return refm(&msgs[14], owner); } +const upb_msgdef *upbdefs_google_protobuf_OneofDescriptorProto_get(const void *owner) { return refm(&msgs[15], owner); } +const upb_msgdef *upbdefs_google_protobuf_ServiceDescriptorProto_get(const void *owner) { return refm(&msgs[16], owner); } +const upb_msgdef *upbdefs_google_protobuf_ServiceOptions_get(const void *owner) { return refm(&msgs[17], owner); } +const upb_msgdef *upbdefs_google_protobuf_SourceCodeInfo_get(const void *owner) { return refm(&msgs[18], owner); } +const upb_msgdef *upbdefs_google_protobuf_SourceCodeInfo_Location_get(const void *owner) { return refm(&msgs[19], owner); } +const upb_msgdef *upbdefs_google_protobuf_UninterpretedOption_get(const void *owner) { return refm(&msgs[20], owner); } +const upb_msgdef *upbdefs_google_protobuf_UninterpretedOption_NamePart_get(const void *owner) { return refm(&msgs[21], owner); } + +const upb_enumdef *upbdefs_google_protobuf_FieldDescriptorProto_Label_get(const void *owner) { return refe(&enums[0], owner); } +const upb_enumdef *upbdefs_google_protobuf_FieldDescriptorProto_Type_get(const void *owner) { return refe(&enums[1], owner); } +const upb_enumdef *upbdefs_google_protobuf_FieldOptions_CType_get(const void *owner) { return refe(&enums[2], owner); } +const upb_enumdef *upbdefs_google_protobuf_FieldOptions_JSType_get(const void *owner) { return refe(&enums[3], owner); } +const upb_enumdef *upbdefs_google_protobuf_FileOptions_OptimizeMode_get(const void *owner) { return refe(&enums[4], owner); } diff --git a/upb/descriptor/reader.c b/upb/descriptor/reader.c new file mode 100644 index 0000000000..054ebd216d --- /dev/null +++ b/upb/descriptor/reader.c @@ -0,0 +1,901 @@ +/* +** XXX: The routines in this file that consume a string do not currently +** support having the string span buffers. In the future, as upb_sink and +** its buffering/sharing functionality evolve there should be an easy and +** idiomatic way of correctly handling this case. For now, we accept this +** limitation since we currently only parse descriptors from single strings. +*/ + +#include "upb/descriptor/reader.h" + +#include +#include +#include +#include "upb/def.h" +#include "upb/sink.h" +#include "upb/descriptor/descriptor.upbdefs.h" + +/* Compares a NULL-terminated string with a non-NULL-terminated string. */ +static bool upb_streq(const char *str, const char *buf, size_t n) { + return strlen(str) == n && memcmp(str, buf, n) == 0; +} + +/* We keep a stack of all the messages scopes we are currently in, as well as + * the top-level file scope. This is necessary to correctly qualify the + * definitions that are contained inside. "name" tracks the name of the + * message or package (a bare name -- not qualified by any enclosing scopes). */ +typedef struct { + char *name; + /* Index of the first def that is under this scope. For msgdefs, the + * msgdef itself is at start-1. */ + int start; + uint32_t oneof_start; + uint32_t oneof_index; +} upb_descreader_frame; + +/* The maximum number of nested declarations that are allowed, ie. + * message Foo { + * message Bar { + * message Baz { + * } + * } + * } + * + * This is a resource limit that affects how big our runtime stack can grow. + * TODO: make this a runtime-settable property of the Reader instance. */ +#define UPB_MAX_MESSAGE_NESTING 64 + +struct upb_descreader { + upb_sink sink; + upb_inttable files; + upb_strtable files_by_name; + upb_filedef *file; /* The last file in files. */ + upb_descreader_frame stack[UPB_MAX_MESSAGE_NESTING]; + int stack_len; + upb_inttable oneofs; + + uint32_t number; + char *name; + bool saw_number; + bool saw_name; + + char *default_string; + + upb_fielddef *f; +}; + +static char *upb_gstrndup(const char *buf, size_t n) { + char *ret = upb_gmalloc(n + 1); + if (!ret) return NULL; + memcpy(ret, buf, n); + ret[n] = '\0'; + return ret; +} + +/* Returns a newly allocated string that joins input strings together, for + * example: + * join("Foo.Bar", "Baz") -> "Foo.Bar.Baz" + * join("", "Baz") -> "Baz" + * Caller owns a ref on the returned string. */ +static char *upb_join(const char *base, const char *name) { + if (!base || strlen(base) == 0) { + return upb_gstrdup(name); + } else { + char *ret = upb_gmalloc(strlen(base) + strlen(name) + 2); + if (!ret) { + return NULL; + } + ret[0] = '\0'; + strcat(ret, base); + strcat(ret, "."); + strcat(ret, name); + return ret; + } +} + +/* Qualify the defname for all defs starting with offset "start" with "str". */ +static bool upb_descreader_qualify(upb_filedef *f, char *str, int32_t start) { + size_t i; + for (i = start; i < upb_filedef_defcount(f); i++) { + upb_def *def = upb_filedef_mutabledef(f, i); + char *name = upb_join(str, upb_def_fullname(def)); + if (!name) { + /* Need better logic here; at this point we've qualified some names but + * not others. */ + return false; + } + upb_def_setfullname(def, name, NULL); + upb_gfree(name); + } + return true; +} + + +/* upb_descreader ************************************************************/ + +static upb_msgdef *upb_descreader_top(upb_descreader *r) { + int index; + UPB_ASSERT(r->stack_len > 1); + index = r->stack[r->stack_len-1].start - 1; + UPB_ASSERT(index >= 0); + return upb_downcast_msgdef_mutable(upb_filedef_mutabledef(r->file, index)); +} + +static upb_def *upb_descreader_last(upb_descreader *r) { + return upb_filedef_mutabledef(r->file, upb_filedef_defcount(r->file) - 1); +} + +/* Start/end handlers for FileDescriptorProto and DescriptorProto (the two + * entities that have names and can contain sub-definitions. */ +void upb_descreader_startcontainer(upb_descreader *r) { + upb_descreader_frame *f = &r->stack[r->stack_len++]; + f->start = upb_filedef_defcount(r->file); + f->oneof_start = upb_inttable_count(&r->oneofs); + f->oneof_index = 0; + f->name = NULL; +} + +bool upb_descreader_endcontainer(upb_descreader *r) { + upb_descreader_frame *f = &r->stack[r->stack_len - 1]; + + while (upb_inttable_count(&r->oneofs) > f->oneof_start) { + upb_oneofdef *o = upb_value_getptr(upb_inttable_pop(&r->oneofs)); + bool ok = upb_msgdef_addoneof(upb_descreader_top(r), o, &r->oneofs, NULL); + UPB_ASSERT(ok); + } + + if (!upb_descreader_qualify(r->file, f->name, f->start)) { + return false; + } + upb_gfree(f->name); + f->name = NULL; + + r->stack_len--; + return true; +} + +void upb_descreader_setscopename(upb_descreader *r, char *str) { + upb_descreader_frame *f = &r->stack[r->stack_len-1]; + upb_gfree(f->name); + f->name = str; +} + +static upb_oneofdef *upb_descreader_getoneof(upb_descreader *r, + uint32_t index) { + bool found; + upb_value val; + upb_descreader_frame *f = &r->stack[r->stack_len-1]; + + /* DescriptorProto messages can be nested, so we will see the nested messages + * between when we see the FieldDescriptorProto and the OneofDescriptorProto. + * We need to preserve the oneofs in between these two things. */ + index += f->oneof_start; + + while (upb_inttable_count(&r->oneofs) <= index) { + upb_inttable_push(&r->oneofs, upb_value_ptr(upb_oneofdef_new(&r->oneofs))); + } + + found = upb_inttable_lookup(&r->oneofs, index, &val); + UPB_ASSERT(found); + return upb_value_getptr(val); +} + +/** Handlers for google.protobuf.FileDescriptorSet. ***************************/ + +static void *fileset_startfile(void *closure, const void *hd) { + upb_descreader *r = closure; + UPB_UNUSED(hd); + r->file = upb_filedef_new(&r->files); + upb_inttable_push(&r->files, upb_value_ptr(r->file)); + return r; +} + +/** Handlers for google.protobuf.FileDescriptorProto. *************************/ + +static bool file_start(void *closure, const void *hd) { + upb_descreader *r = closure; + UPB_UNUSED(hd); + upb_descreader_startcontainer(r); + return true; +} + +static bool file_end(void *closure, const void *hd, upb_status *status) { + upb_descreader *r = closure; + UPB_UNUSED(hd); + UPB_UNUSED(status); + return upb_descreader_endcontainer(r); +} + +static size_t file_onname(void *closure, const void *hd, const char *buf, + size_t n, const upb_bufhandle *handle) { + upb_descreader *r = closure; + char *name; + bool ok; + UPB_UNUSED(hd); + UPB_UNUSED(handle); + + name = upb_gstrndup(buf, n); + upb_strtable_insert(&r->files_by_name, name, upb_value_ptr(r->file)); + /* XXX: see comment at the top of the file. */ + ok = upb_filedef_setname(r->file, name, NULL); + upb_gfree(name); + UPB_ASSERT(ok); + return n; +} + +static size_t file_onpackage(void *closure, const void *hd, const char *buf, + size_t n, const upb_bufhandle *handle) { + upb_descreader *r = closure; + char *package; + bool ok; + UPB_UNUSED(hd); + UPB_UNUSED(handle); + + package = upb_gstrndup(buf, n); + /* XXX: see comment at the top of the file. */ + upb_descreader_setscopename(r, package); + ok = upb_filedef_setpackage(r->file, package, NULL); + UPB_ASSERT(ok); + return n; +} + +static void *file_startphpnamespace(void *closure, const void *hd, + size_t size_hint) { + upb_descreader *r = closure; + bool ok; + UPB_UNUSED(hd); + UPB_UNUSED(size_hint); + + ok = upb_filedef_setphpnamespace(r->file, "", NULL); + UPB_ASSERT(ok); + return closure; +} + +static size_t file_onphpnamespace(void *closure, const void *hd, + const char *buf, size_t n, + const upb_bufhandle *handle) { + upb_descreader *r = closure; + char *php_namespace; + bool ok; + UPB_UNUSED(hd); + UPB_UNUSED(handle); + + php_namespace = upb_gstrndup(buf, n); + ok = upb_filedef_setphpnamespace(r->file, php_namespace, NULL); + upb_gfree(php_namespace); + UPB_ASSERT(ok); + return n; +} + +static size_t file_onphpprefix(void *closure, const void *hd, const char *buf, + size_t n, const upb_bufhandle *handle) { + upb_descreader *r = closure; + char *prefix; + bool ok; + UPB_UNUSED(hd); + UPB_UNUSED(handle); + + prefix = upb_gstrndup(buf, n); + ok = upb_filedef_setphpprefix(r->file, prefix, NULL); + upb_gfree(prefix); + UPB_ASSERT(ok); + return n; +} + +static size_t file_onsyntax(void *closure, const void *hd, const char *buf, + size_t n, const upb_bufhandle *handle) { + upb_descreader *r = closure; + bool ok; + UPB_UNUSED(hd); + UPB_UNUSED(handle); + /* XXX: see comment at the top of the file. */ + if (upb_streq("proto2", buf, n)) { + ok = upb_filedef_setsyntax(r->file, UPB_SYNTAX_PROTO2, NULL); + } else if (upb_streq("proto3", buf, n)) { + ok = upb_filedef_setsyntax(r->file, UPB_SYNTAX_PROTO3, NULL); + } else { + ok = false; + } + + UPB_ASSERT(ok); + return n; +} + +static void *file_startmsg(void *closure, const void *hd) { + upb_descreader *r = closure; + upb_msgdef *m = upb_msgdef_new(&m); + bool ok = upb_filedef_addmsg(r->file, m, &m, NULL); + UPB_UNUSED(hd); + UPB_ASSERT(ok); + return r; +} + +static void *file_startenum(void *closure, const void *hd) { + upb_descreader *r = closure; + upb_enumdef *e = upb_enumdef_new(&e); + bool ok = upb_filedef_addenum(r->file, e, &e, NULL); + UPB_UNUSED(hd); + UPB_ASSERT(ok); + return r; +} + +static void *file_startext(void *closure, const void *hd) { + upb_descreader *r = closure; + bool ok; + r->f = upb_fielddef_new(r); + ok = upb_filedef_addext(r->file, r->f, r, NULL); + UPB_UNUSED(hd); + UPB_ASSERT(ok); + return r; +} + +static size_t file_ondep(void *closure, const void *hd, const char *buf, + size_t n, const upb_bufhandle *handle) { + upb_descreader *r = closure; + upb_value val; + if (upb_strtable_lookup2(&r->files_by_name, buf, n, &val)) { + upb_filedef_adddep(r->file, upb_value_getptr(val)); + } + UPB_UNUSED(hd); + UPB_UNUSED(handle); + return n; +} + +/** Handlers for google.protobuf.EnumValueDescriptorProto. *********************/ + +static bool enumval_startmsg(void *closure, const void *hd) { + upb_descreader *r = closure; + UPB_UNUSED(hd); + r->saw_number = false; + r->saw_name = false; + return true; +} + +static size_t enumval_onname(void *closure, const void *hd, const char *buf, + size_t n, const upb_bufhandle *handle) { + upb_descreader *r = closure; + UPB_UNUSED(hd); + UPB_UNUSED(handle); + /* XXX: see comment at the top of the file. */ + upb_gfree(r->name); + r->name = upb_gstrndup(buf, n); + r->saw_name = true; + return n; +} + +static bool enumval_onnumber(void *closure, const void *hd, int32_t val) { + upb_descreader *r = closure; + UPB_UNUSED(hd); + r->number = val; + r->saw_number = true; + return true; +} + +static bool enumval_endmsg(void *closure, const void *hd, upb_status *status) { + upb_descreader *r = closure; + upb_enumdef *e; + UPB_UNUSED(hd); + + if(!r->saw_number || !r->saw_name) { + upb_status_seterrmsg(status, "Enum value missing name or number."); + return false; + } + e = upb_downcast_enumdef_mutable(upb_descreader_last(r)); + upb_enumdef_addval(e, r->name, r->number, status); + upb_gfree(r->name); + r->name = NULL; + return true; +} + +/** Handlers for google.protobuf.EnumDescriptorProto. *************************/ + +static bool enum_endmsg(void *closure, const void *hd, upb_status *status) { + upb_descreader *r = closure; + upb_enumdef *e; + UPB_UNUSED(hd); + + e = upb_downcast_enumdef_mutable(upb_descreader_last(r)); + if (upb_def_fullname(upb_descreader_last(r)) == NULL) { + upb_status_seterrmsg(status, "Enum had no name."); + return false; + } + if (upb_enumdef_numvals(e) == 0) { + upb_status_seterrmsg(status, "Enum had no values."); + return false; + } + return true; +} + +static size_t enum_onname(void *closure, const void *hd, const char *buf, + size_t n, const upb_bufhandle *handle) { + upb_descreader *r = closure; + char *fullname = upb_gstrndup(buf, n); + UPB_UNUSED(hd); + UPB_UNUSED(handle); + /* XXX: see comment at the top of the file. */ + upb_def_setfullname(upb_descreader_last(r), fullname, NULL); + upb_gfree(fullname); + return n; +} + +/** Handlers for google.protobuf.FieldDescriptorProto *************************/ + +static bool field_startmsg(void *closure, const void *hd) { + upb_descreader *r = closure; + UPB_UNUSED(hd); + UPB_ASSERT(r->f); + upb_gfree(r->default_string); + r->default_string = NULL; + + /* fielddefs default to packed, but descriptors default to non-packed. */ + upb_fielddef_setpacked(r->f, false); + return true; +} + +/* Converts the default value in string "str" into "d". Passes a ref on str. + * Returns true on success. */ +static bool parse_default(char *str, upb_fielddef *f) { + bool success = true; + char *end; + switch (upb_fielddef_type(f)) { + case UPB_TYPE_INT32: { + long val = strtol(str, &end, 0); + if (val > INT32_MAX || val < INT32_MIN || errno == ERANGE || *end) + success = false; + else + upb_fielddef_setdefaultint32(f, val); + break; + } + case UPB_TYPE_INT64: { + /* XXX: Need to write our own strtoll, since it's not available in c89. */ + long long val = strtol(str, &end, 0); + if (val > INT64_MAX || val < INT64_MIN || errno == ERANGE || *end) + success = false; + else + upb_fielddef_setdefaultint64(f, val); + break; + } + case UPB_TYPE_UINT32: { + unsigned long val = strtoul(str, &end, 0); + if (val > UINT32_MAX || errno == ERANGE || *end) + success = false; + else + upb_fielddef_setdefaultuint32(f, val); + break; + } + case UPB_TYPE_UINT64: { + /* XXX: Need to write our own strtoull, since it's not available in c89. */ + unsigned long long val = strtoul(str, &end, 0); + if (val > UINT64_MAX || errno == ERANGE || *end) + success = false; + else + upb_fielddef_setdefaultuint64(f, val); + break; + } + case UPB_TYPE_DOUBLE: { + double val = strtod(str, &end); + if (errno == ERANGE || *end) + success = false; + else + upb_fielddef_setdefaultdouble(f, val); + break; + } + case UPB_TYPE_FLOAT: { + /* XXX: Need to write our own strtof, since it's not available in c89. */ + float val = strtod(str, &end); + if (errno == ERANGE || *end) + success = false; + else + upb_fielddef_setdefaultfloat(f, val); + break; + } + case UPB_TYPE_BOOL: { + if (strcmp(str, "false") == 0) + upb_fielddef_setdefaultbool(f, false); + else if (strcmp(str, "true") == 0) + upb_fielddef_setdefaultbool(f, true); + else + success = false; + break; + } + default: abort(); + } + return success; +} + +static bool field_endmsg(void *closure, const void *hd, upb_status *status) { + upb_descreader *r = closure; + upb_fielddef *f = r->f; + UPB_UNUSED(hd); + + /* TODO: verify that all required fields were present. */ + UPB_ASSERT(upb_fielddef_number(f) != 0); + UPB_ASSERT(upb_fielddef_name(f) != NULL); + UPB_ASSERT((upb_fielddef_subdefname(f) != NULL) == upb_fielddef_hassubdef(f)); + + if (r->default_string) { + if (upb_fielddef_issubmsg(f)) { + upb_status_seterrmsg(status, "Submessages cannot have defaults."); + return false; + } + if (upb_fielddef_isstring(f) || upb_fielddef_type(f) == UPB_TYPE_ENUM) { + upb_fielddef_setdefaultcstr(f, r->default_string, NULL); + } else { + if (r->default_string && !parse_default(r->default_string, f)) { + /* We don't worry too much about giving a great error message since the + * compiler should have ensured this was correct. */ + upb_status_seterrmsg(status, "Error converting default value."); + return false; + } + } + } + return true; +} + +static bool field_onlazy(void *closure, const void *hd, bool val) { + upb_descreader *r = closure; + UPB_UNUSED(hd); + + upb_fielddef_setlazy(r->f, val); + return true; +} + +static bool field_onpacked(void *closure, const void *hd, bool val) { + upb_descreader *r = closure; + UPB_UNUSED(hd); + + upb_fielddef_setpacked(r->f, val); + return true; +} + +static bool field_ontype(void *closure, const void *hd, int32_t val) { + upb_descreader *r = closure; + UPB_UNUSED(hd); + + upb_fielddef_setdescriptortype(r->f, val); + return true; +} + +static bool field_onlabel(void *closure, const void *hd, int32_t val) { + upb_descreader *r = closure; + UPB_UNUSED(hd); + + upb_fielddef_setlabel(r->f, val); + return true; +} + +static bool field_onnumber(void *closure, const void *hd, int32_t val) { + upb_descreader *r = closure; + bool ok; + UPB_UNUSED(hd); + + ok = upb_fielddef_setnumber(r->f, val, NULL); + UPB_ASSERT(ok); + return true; +} + +static size_t field_onname(void *closure, const void *hd, const char *buf, + size_t n, const upb_bufhandle *handle) { + upb_descreader *r = closure; + char *name = upb_gstrndup(buf, n); + UPB_UNUSED(hd); + UPB_UNUSED(handle); + + /* XXX: see comment at the top of the file. */ + upb_fielddef_setname(r->f, name, NULL); + upb_gfree(name); + return n; +} + +static size_t field_ontypename(void *closure, const void *hd, const char *buf, + size_t n, const upb_bufhandle *handle) { + upb_descreader *r = closure; + char *name = upb_gstrndup(buf, n); + UPB_UNUSED(hd); + UPB_UNUSED(handle); + + /* XXX: see comment at the top of the file. */ + upb_fielddef_setsubdefname(r->f, name, NULL); + upb_gfree(name); + return n; +} + +static size_t field_onextendee(void *closure, const void *hd, const char *buf, + size_t n, const upb_bufhandle *handle) { + upb_descreader *r = closure; + char *name = upb_gstrndup(buf, n); + UPB_UNUSED(hd); + UPB_UNUSED(handle); + + /* XXX: see comment at the top of the file. */ + upb_fielddef_setcontainingtypename(r->f, name, NULL); + upb_gfree(name); + return n; +} + +static size_t field_ondefaultval(void *closure, const void *hd, const char *buf, + size_t n, const upb_bufhandle *handle) { + upb_descreader *r = closure; + UPB_UNUSED(hd); + UPB_UNUSED(handle); + + /* Have to convert from string to the correct type, but we might not know the + * type yet, so we save it as a string until the end of the field. + * XXX: see comment at the top of the file. */ + upb_gfree(r->default_string); + r->default_string = upb_gstrndup(buf, n); + return n; +} + +static bool field_ononeofindex(void *closure, const void *hd, int32_t index) { + upb_descreader *r = closure; + upb_oneofdef *o = upb_descreader_getoneof(r, index); + bool ok = upb_oneofdef_addfield(o, r->f, &r->f, NULL); + UPB_UNUSED(hd); + + UPB_ASSERT(ok); + return true; +} + +/** Handlers for google.protobuf.OneofDescriptorProto. ************************/ + +static size_t oneof_name(void *closure, const void *hd, const char *buf, + size_t n, const upb_bufhandle *handle) { + upb_descreader *r = closure; + upb_descreader_frame *f = &r->stack[r->stack_len-1]; + upb_oneofdef *o = upb_descreader_getoneof(r, f->oneof_index++); + char *name_null_terminated = upb_gstrndup(buf, n); + bool ok = upb_oneofdef_setname(o, name_null_terminated, NULL); + UPB_UNUSED(hd); + UPB_UNUSED(handle); + + UPB_ASSERT(ok); + free(name_null_terminated); + return n; +} + +/** Handlers for google.protobuf.DescriptorProto ******************************/ + +static bool msg_start(void *closure, const void *hd) { + upb_descreader *r = closure; + UPB_UNUSED(hd); + + upb_descreader_startcontainer(r); + return true; +} + +static bool msg_end(void *closure, const void *hd, upb_status *status) { + upb_descreader *r = closure; + upb_msgdef *m = upb_descreader_top(r); + UPB_UNUSED(hd); + + if(!upb_def_fullname(upb_msgdef_upcast_mutable(m))) { + upb_status_seterrmsg(status, "Encountered message with no name."); + return false; + } + return upb_descreader_endcontainer(r); +} + +static size_t msg_name(void *closure, const void *hd, const char *buf, + size_t n, const upb_bufhandle *handle) { + upb_descreader *r = closure; + upb_msgdef *m = upb_descreader_top(r); + /* XXX: see comment at the top of the file. */ + char *name = upb_gstrndup(buf, n); + UPB_UNUSED(hd); + UPB_UNUSED(handle); + + upb_def_setfullname(upb_msgdef_upcast_mutable(m), name, NULL); + upb_descreader_setscopename(r, name); /* Passes ownership of name. */ + + return n; +} + +static void *msg_startmsg(void *closure, const void *hd) { + upb_descreader *r = closure; + upb_msgdef *m = upb_msgdef_new(&m); + bool ok = upb_filedef_addmsg(r->file, m, &m, NULL); + UPB_UNUSED(hd); + UPB_ASSERT(ok); + return r; +} + +static void *msg_startext(void *closure, const void *hd) { + upb_descreader *r = closure; + upb_fielddef *f = upb_fielddef_new(&f); + bool ok = upb_filedef_addext(r->file, f, &f, NULL); + UPB_UNUSED(hd); + UPB_ASSERT(ok); + return r; +} + +static void *msg_startfield(void *closure, const void *hd) { + upb_descreader *r = closure; + r->f = upb_fielddef_new(&r->f); + /* We can't add the new field to the message until its name/number are + * filled in. */ + UPB_UNUSED(hd); + return r; +} + +static bool msg_endfield(void *closure, const void *hd) { + upb_descreader *r = closure; + upb_msgdef *m = upb_descreader_top(r); + bool ok; + UPB_UNUSED(hd); + + /* Oneof fields are added to the msgdef through their oneof, so don't need to + * be added here. */ + if (upb_fielddef_containingoneof(r->f) == NULL) { + ok = upb_msgdef_addfield(m, r->f, &r->f, NULL); + UPB_ASSERT(ok); + } + r->f = NULL; + return true; +} + +static bool msg_onmapentry(void *closure, const void *hd, bool mapentry) { + upb_descreader *r = closure; + upb_msgdef *m = upb_descreader_top(r); + UPB_UNUSED(hd); + + upb_msgdef_setmapentry(m, mapentry); + r->f = NULL; + return true; +} + + + +/** Code to register handlers *************************************************/ + +#define F(msg, field) upbdefs_google_protobuf_ ## msg ## _f_ ## field(m) + +static void reghandlers(const void *closure, upb_handlers *h) { + const upb_msgdef *m = upb_handlers_msgdef(h); + UPB_UNUSED(closure); + + if (upbdefs_google_protobuf_FileDescriptorSet_is(m)) { + upb_handlers_setstartsubmsg(h, F(FileDescriptorSet, file), + &fileset_startfile, NULL); + } else if (upbdefs_google_protobuf_DescriptorProto_is(m)) { + upb_handlers_setstartmsg(h, &msg_start, NULL); + upb_handlers_setendmsg(h, &msg_end, NULL); + upb_handlers_setstring(h, F(DescriptorProto, name), &msg_name, NULL); + upb_handlers_setstartsubmsg(h, F(DescriptorProto, extension), &msg_startext, + NULL); + upb_handlers_setstartsubmsg(h, F(DescriptorProto, nested_type), + &msg_startmsg, NULL); + upb_handlers_setstartsubmsg(h, F(DescriptorProto, field), + &msg_startfield, NULL); + upb_handlers_setendsubmsg(h, F(DescriptorProto, field), + &msg_endfield, NULL); + upb_handlers_setstartsubmsg(h, F(DescriptorProto, enum_type), + &file_startenum, NULL); + } else if (upbdefs_google_protobuf_FileDescriptorProto_is(m)) { + upb_handlers_setstartmsg(h, &file_start, NULL); + upb_handlers_setendmsg(h, &file_end, NULL); + upb_handlers_setstring(h, F(FileDescriptorProto, name), &file_onname, + NULL); + upb_handlers_setstring(h, F(FileDescriptorProto, package), &file_onpackage, + NULL); + upb_handlers_setstring(h, F(FileDescriptorProto, syntax), &file_onsyntax, + NULL); + upb_handlers_setstartsubmsg(h, F(FileDescriptorProto, message_type), + &file_startmsg, NULL); + upb_handlers_setstartsubmsg(h, F(FileDescriptorProto, enum_type), + &file_startenum, NULL); + upb_handlers_setstartsubmsg(h, F(FileDescriptorProto, extension), + &file_startext, NULL); + upb_handlers_setstring(h, F(FileDescriptorProto, dependency), + &file_ondep, NULL); + } else if (upbdefs_google_protobuf_EnumValueDescriptorProto_is(m)) { + upb_handlers_setstartmsg(h, &enumval_startmsg, NULL); + upb_handlers_setendmsg(h, &enumval_endmsg, NULL); + upb_handlers_setstring(h, F(EnumValueDescriptorProto, name), &enumval_onname, NULL); + upb_handlers_setint32(h, F(EnumValueDescriptorProto, number), &enumval_onnumber, + NULL); + } else if (upbdefs_google_protobuf_EnumDescriptorProto_is(m)) { + upb_handlers_setendmsg(h, &enum_endmsg, NULL); + upb_handlers_setstring(h, F(EnumDescriptorProto, name), &enum_onname, NULL); + } else if (upbdefs_google_protobuf_FieldDescriptorProto_is(m)) { + upb_handlers_setstartmsg(h, &field_startmsg, NULL); + upb_handlers_setendmsg(h, &field_endmsg, NULL); + upb_handlers_setint32(h, F(FieldDescriptorProto, type), &field_ontype, + NULL); + upb_handlers_setint32(h, F(FieldDescriptorProto, label), &field_onlabel, + NULL); + upb_handlers_setint32(h, F(FieldDescriptorProto, number), &field_onnumber, + NULL); + upb_handlers_setstring(h, F(FieldDescriptorProto, name), &field_onname, + NULL); + upb_handlers_setstring(h, F(FieldDescriptorProto, type_name), + &field_ontypename, NULL); + upb_handlers_setstring(h, F(FieldDescriptorProto, extendee), + &field_onextendee, NULL); + upb_handlers_setstring(h, F(FieldDescriptorProto, default_value), + &field_ondefaultval, NULL); + upb_handlers_setint32(h, F(FieldDescriptorProto, oneof_index), + &field_ononeofindex, NULL); + } else if (upbdefs_google_protobuf_OneofDescriptorProto_is(m)) { + upb_handlers_setstring(h, F(OneofDescriptorProto, name), &oneof_name, NULL); + } else if (upbdefs_google_protobuf_FieldOptions_is(m)) { + upb_handlers_setbool(h, F(FieldOptions, lazy), &field_onlazy, NULL); + upb_handlers_setbool(h, F(FieldOptions, packed), &field_onpacked, NULL); + } else if (upbdefs_google_protobuf_MessageOptions_is(m)) { + upb_handlers_setbool(h, F(MessageOptions, map_entry), &msg_onmapentry, NULL); + } else if (upbdefs_google_protobuf_FileOptions_is(m)) { + upb_handlers_setstring(h, F(FileOptions, php_class_prefix), + &file_onphpprefix, NULL); + upb_handlers_setstartstr(h, F(FileOptions, php_namespace), + &file_startphpnamespace, NULL); + upb_handlers_setstring(h, F(FileOptions, php_namespace), + &file_onphpnamespace, NULL); + } + + UPB_ASSERT(upb_ok(upb_handlers_status(h))); +} + +#undef F + +void descreader_cleanup(void *_r) { + upb_descreader *r = _r; + size_t i; + + for (i = 0; i < upb_descreader_filecount(r); i++) { + upb_filedef_unref(upb_descreader_file(r, i), &r->files); + } + + upb_gfree(r->name); + upb_inttable_uninit(&r->files); + upb_strtable_uninit(&r->files_by_name); + upb_inttable_uninit(&r->oneofs); + upb_gfree(r->default_string); + while (r->stack_len > 0) { + upb_descreader_frame *f = &r->stack[--r->stack_len]; + upb_gfree(f->name); + } +} + + +/* Public API ****************************************************************/ + +upb_descreader *upb_descreader_create(upb_env *e, const upb_handlers *h) { + upb_descreader *r = upb_env_malloc(e, sizeof(upb_descreader)); + if (!r || !upb_env_addcleanup(e, descreader_cleanup, r)) { + return NULL; + } + + upb_inttable_init(&r->files, UPB_CTYPE_PTR); + upb_strtable_init(&r->files_by_name, UPB_CTYPE_PTR); + upb_inttable_init(&r->oneofs, UPB_CTYPE_PTR); + upb_sink_reset(upb_descreader_input(r), h, r); + r->stack_len = 0; + r->name = NULL; + r->default_string = NULL; + + return r; +} + +size_t upb_descreader_filecount(const upb_descreader *r) { + return upb_inttable_count(&r->files); +} + +upb_filedef *upb_descreader_file(const upb_descreader *r, size_t i) { + upb_value v; + if (upb_inttable_lookup(&r->files, i, &v)) { + return upb_value_getptr(v); + } else { + return NULL; + } +} + +upb_sink *upb_descreader_input(upb_descreader *r) { + return &r->sink; +} + +const upb_handlers *upb_descreader_newhandlers(const void *owner) { + const upb_msgdef *m = upbdefs_google_protobuf_FileDescriptorSet_get(&m); + const upb_handlers *h = upb_handlers_newfrozen(m, owner, reghandlers, NULL); + upb_msgdef_unref(m, &m); + return h; +} diff --git a/upb/json/parser.c b/upb/json/parser.c index 53e31a120b..3ae4722377 100644 --- a/upb/json/parser.c +++ b/upb/json/parser.c @@ -39,16 +39,6 @@ #define UPB_JSON_MAX_DEPTH 64 -static const char *kDoubleValueFullMessageName = "google.protobuf.DoubleValue"; -static const char *kFloatValueFullMessageName = "google.protobuf.FloatValue"; -static const char *kInt64ValueFullMessageName = "google.protobuf.Int64Value"; -static const char *kUInt64ValueFullMessageName = "google.protobuf.UInt64Value"; -static const char *kInt32ValueFullMessageName = "google.protobuf.Int32Value"; -static const char *kUInt32ValueFullMessageName = "google.protobuf.UInt32Value"; -static const char *kBoolValueFullMessageName = "google.protobuf.BoolValue"; -static const char *kStringValueFullMessageName = "google.protobuf.StringValue"; -static const char *kBytesValueFullMessageName = "google.protobuf.BytesValue"; - /* Type of value message */ enum { VALUE_NULLVALUE = 0, @@ -61,6 +51,8 @@ enum { /* Forward declare */ static bool is_top_level(upb_json_parser *p); +static bool is_wellknown_msg(upb_json_parser *p, upb_wellknowntype_t type); +static bool is_wellknown_field(upb_json_parser *p, upb_wellknowntype_t type); static bool is_number_wrapper_object(upb_json_parser *p); static bool does_number_wrapper_start(upb_json_parser *p); @@ -70,30 +62,6 @@ static bool is_string_wrapper_object(upb_json_parser *p); static bool does_string_wrapper_start(upb_json_parser *p); static bool does_string_wrapper_end(upb_json_parser *p); -static bool is_boolean_wrapper_object(upb_json_parser *p); -static bool does_boolean_wrapper_start(upb_json_parser *p); -static bool does_boolean_wrapper_end(upb_json_parser *p); - -static bool is_duration_object(upb_json_parser *p); -static bool does_duration_start(upb_json_parser *p); -static bool does_duration_end(upb_json_parser *p); - -static bool is_timestamp_object(upb_json_parser *p); -static bool does_timestamp_start(upb_json_parser *p); -static bool does_timestamp_end(upb_json_parser *p); - -static bool is_value_object(upb_json_parser *p); -static bool does_value_start(upb_json_parser *p); -static bool does_value_end(upb_json_parser *p); - -static bool is_listvalue_object(upb_json_parser *p); -static bool does_listvalue_start(upb_json_parser *p); -static bool does_listvalue_end(upb_json_parser *p); - -static bool is_structvalue_object(upb_json_parser *p); -static bool does_structvalue_start(upb_json_parser *p); -static bool does_structvalue_end(upb_json_parser *p); - static void start_wrapper_object(upb_json_parser *p); static void end_wrapper_object(upb_json_parser *p); @@ -145,6 +113,9 @@ typedef struct { * because |f| is the field in the *current* message (i.e., the map-entry * message itself), not the parent's field that leads to this map. */ const upb_fielddef *mapfield; + + /* True if the field to be parsed is unknown. */ + bool is_unknown_field; } upb_jsonparser_frame; struct upb_json_parser { @@ -701,7 +672,7 @@ static bool start_number(upb_json_parser *p, const char *ptr) { if (is_top_level(p)) { if (is_number_wrapper_object(p)) { start_wrapper_object(p); - } else if (is_value_object(p)) { + } else if (is_wellknown_msg(p, UPB_WELLKNOWN_VALUE)) { start_value_object(p, VALUE_NUMBERVALUE); } else { return false; @@ -711,7 +682,7 @@ static bool start_number(upb_json_parser *p, const char *ptr) { return false; } start_wrapper_object(p); - } else if (does_value_start(p)) { + } else if (is_wellknown_field(p, UPB_WELLKNOWN_VALUE)) { if (!start_subobject(p)) { return false; } @@ -751,7 +722,7 @@ static bool end_number(upb_json_parser *p, const char *ptr) { return true; } - if (does_value_end(p)) { + if (is_wellknown_msg(p, UPB_WELLKNOWN_VALUE)) { end_value_object(p); if (!is_top_level(p)) { end_subobject(p); @@ -931,30 +902,34 @@ static bool parser_putbool(upb_json_parser *p, bool val) { static bool end_bool(upb_json_parser *p, bool val) { if (is_top_level(p)) { - if (is_boolean_wrapper_object(p)) { + if (is_wellknown_msg(p, UPB_WELLKNOWN_BOOLVALUE)) { start_wrapper_object(p); - } else if (is_value_object(p)) { + } else if (is_wellknown_msg(p, UPB_WELLKNOWN_VALUE)) { start_value_object(p, VALUE_BOOLVALUE); } else { return false; } - } else if (does_boolean_wrapper_start(p)) { + } else if (is_wellknown_field(p, UPB_WELLKNOWN_BOOLVALUE)) { if (!start_subobject(p)) { return false; } start_wrapper_object(p); - } else if (does_value_start(p)) { + } else if (is_wellknown_field(p, UPB_WELLKNOWN_VALUE)) { if (!start_subobject(p)) { return false; } start_value_object(p, VALUE_BOOLVALUE); } + if (p->top->is_unknown_field) { + return true; + } + if (!parser_putbool(p, val)) { return false; } - if (does_boolean_wrapper_end(p)) { + if (is_wellknown_msg(p, UPB_WELLKNOWN_BOOLVALUE)) { end_wrapper_object(p); if (!is_top_level(p)) { end_subobject(p); @@ -962,7 +937,7 @@ static bool end_bool(upb_json_parser *p, bool val) { return true; } - if (does_value_end(p)) { + if (is_wellknown_msg(p, UPB_WELLKNOWN_VALUE)) { end_value_object(p); if (!is_top_level(p)) { end_subobject(p); @@ -977,12 +952,12 @@ static bool end_null(upb_json_parser *p) { const char *zero_ptr = "0"; if (is_top_level(p)) { - if (is_value_object(p)) { + if (is_wellknown_msg(p, UPB_WELLKNOWN_VALUE)) { start_value_object(p, VALUE_NULLVALUE); } else { return true; } - } else if (does_value_start(p)) { + } else if (is_wellknown_field(p, UPB_WELLKNOWN_VALUE)) { if (!start_subobject(p)) { return false; } @@ -1009,9 +984,10 @@ static bool start_stringval(upb_json_parser *p) { if (is_top_level(p)) { if (is_string_wrapper_object(p)) { start_wrapper_object(p); - } else if (is_timestamp_object(p) || is_duration_object(p)) { + } else if (is_wellknown_msg(p, UPB_WELLKNOWN_TIMESTAMP) || + is_wellknown_msg(p, UPB_WELLKNOWN_DURATION)) { start_object(p); - } else if (is_value_object(p)) { + } else if (is_wellknown_msg(p, UPB_WELLKNOWN_VALUE)) { start_value_object(p, VALUE_STRINGVALUE); } else { return false; @@ -1021,12 +997,13 @@ static bool start_stringval(upb_json_parser *p) { return false; } start_wrapper_object(p); - } else if (does_timestamp_start(p) || does_duration_start(p)) { + } else if (is_wellknown_field(p, UPB_WELLKNOWN_TIMESTAMP) || + is_wellknown_field(p, UPB_WELLKNOWN_DURATION)) { if (!start_subobject(p)) { return false; } start_object(p); - } else if (does_value_start(p)) { + } else if (is_wellknown_field(p, UPB_WELLKNOWN_VALUE)) { if (!start_subobject(p)) { return false; } @@ -1054,6 +1031,7 @@ static bool start_stringval(upb_json_parser *p) { inner->name_table = NULL; inner->is_map = false; inner->is_mapentry = false; + inner->is_unknown_field = false; p->top = inner; if (upb_fielddef_type(p->top->f) == UPB_TYPE_STRING) { @@ -1087,7 +1065,8 @@ static bool start_stringval(upb_json_parser *p) { static bool end_stringval_nontop(upb_json_parser *p) { bool ok = true; - if (is_timestamp_object(p) || is_duration_object(p)) { + if (is_wellknown_msg(p, UPB_WELLKNOWN_TIMESTAMP) || + is_wellknown_msg(p, UPB_WELLKNOWN_DURATION)) { multipart_end(p); return true; } @@ -1169,7 +1148,7 @@ static bool end_stringval(upb_json_parser *p) { return true; } - if (does_value_end(p)) { + if (is_wellknown_msg(p, UPB_WELLKNOWN_VALUE)) { end_value_object(p); if (!is_top_level(p)) { end_subobject(p); @@ -1177,7 +1156,8 @@ static bool end_stringval(upb_json_parser *p) { return true; } - if (does_timestamp_end(p) || does_duration_end(p)) { + if (is_wellknown_msg(p, UPB_WELLKNOWN_TIMESTAMP) || + is_wellknown_msg(p, UPB_WELLKNOWN_DURATION)) { end_object(p); if (!is_top_level(p)) { end_subobject(p); @@ -1289,18 +1269,26 @@ static void start_timestamp_base(upb_json_parser *p, const char *ptr) { capture_begin(p, ptr); } +#define UPB_TIMESTAMP_BASE_SIZE 19 + static bool end_timestamp_base(upb_json_parser *p, const char *ptr) { size_t len; const char *buf; + /* 3 for GMT and 1 for ending 0 */ + char timestamp_buf[UPB_TIMESTAMP_BASE_SIZE + 4]; if (!capture_end(p, ptr)) { return false; } buf = accumulate_getptr(p, &len); + UPB_ASSERT(len == UPB_TIMESTAMP_BASE_SIZE); + memcpy(timestamp_buf, buf, UPB_TIMESTAMP_BASE_SIZE); + memcpy(timestamp_buf + UPB_TIMESTAMP_BASE_SIZE, "GMT", 3); + timestamp_buf[UPB_TIMESTAMP_BASE_SIZE + 3] = 0; /* Parse seconds */ - if (strptime(buf, "%FT%H:%M:%S", &p->tm) == NULL) { + if (strptime(timestamp_buf, "%FT%H:%M:%S%Z", &p->tm) == NULL) { upb_status_seterrf(&p->status, "error parsing timestamp: %s", buf); upb_env_reporterror(p->env, &p->status); return false; @@ -1535,6 +1523,7 @@ static bool handle_mapentry(upb_json_parser *p) { inner->name_table = NULL; inner->mapfield = mapfield; inner->is_map = false; + inner->is_unknown_field = false; /* Don't set this to true *yet* -- we reuse parsing handlers below to push * the key field value to the sink, and these handlers will pop the frame @@ -1565,6 +1554,8 @@ static bool end_membername(upb_json_parser *p) { UPB_ASSERT(!p->top->f); if (!p->top->m) { + p->top->is_unknown_field = true; + multipart_end(p); return true; } @@ -1581,6 +1572,7 @@ static bool end_membername(upb_json_parser *p) { return true; } else if (p->ignore_json_unknown) { + p->top->is_unknown_field = true; multipart_end(p); return true; } else { @@ -1612,10 +1604,11 @@ static void end_member(upb_json_parser *p) { } p->top->f = NULL; + p->top->is_unknown_field = false; } static bool start_subobject(upb_json_parser *p) { - if (p->top->f == NULL) { + if (p->top->is_unknown_field) { upb_jsonparser_frame *inner; if (!check_stack(p)) return false; @@ -1624,6 +1617,7 @@ static bool start_subobject(upb_json_parser *p) { inner->f = NULL; inner->is_map = false; inner->is_mapentry = false; + inner->is_unknown_field = false; p->top = inner; return true; } @@ -1645,6 +1639,7 @@ static bool start_subobject(upb_json_parser *p) { inner->f = NULL; inner->is_map = true; inner->is_mapentry = false; + inner->is_unknown_field = false; p->top = inner; return true; @@ -1665,6 +1660,7 @@ static bool start_subobject(upb_json_parser *p) { inner->f = NULL; inner->is_map = false; inner->is_mapentry = false; + inner->is_unknown_field = false; p->top = inner; return true; @@ -1679,19 +1675,19 @@ static bool start_subobject(upb_json_parser *p) { static bool start_subobject_full(upb_json_parser *p) { if (is_top_level(p)) { - if (is_value_object(p)) { + if (is_wellknown_msg(p, UPB_WELLKNOWN_VALUE)) { start_value_object(p, VALUE_STRUCTVALUE); if (!start_subobject(p)) return false; start_structvalue_object(p); - } else if (is_structvalue_object(p)) { + } else if (is_wellknown_msg(p, UPB_WELLKNOWN_STRUCT)) { start_structvalue_object(p); } else { return true; } - } else if (does_structvalue_start(p)) { + } else if (is_wellknown_field(p, UPB_WELLKNOWN_STRUCT)) { if (!start_subobject(p)) return false; start_structvalue_object(p); - } else if (does_value_start(p)) { + } else if (is_wellknown_field(p, UPB_WELLKNOWN_VALUE)) { if (!start_subobject(p)) return false; start_value_object(p, VALUE_STRUCTVALUE); if (!start_subobject(p)) return false; @@ -1725,14 +1721,14 @@ static void end_subobject(upb_json_parser *p) { static void end_subobject_full(upb_json_parser *p) { end_subobject(p); - if (does_structvalue_end(p)) { + if (is_wellknown_msg(p, UPB_WELLKNOWN_STRUCT)) { end_structvalue_object(p); if (!is_top_level(p)) { end_subobject(p); } } - if (does_value_end(p)) { + if (is_wellknown_msg(p, UPB_WELLKNOWN_VALUE)) { end_value_object(p); if (!is_top_level(p)) { end_subobject(p); @@ -1745,26 +1741,37 @@ static bool start_array(upb_json_parser *p) { upb_selector_t sel; if (is_top_level(p)) { - if (is_value_object(p)) { + if (is_wellknown_msg(p, UPB_WELLKNOWN_VALUE)) { start_value_object(p, VALUE_LISTVALUE); if (!start_subobject(p)) return false; start_listvalue_object(p); - } else if (is_listvalue_object(p)) { + } else if (is_wellknown_msg(p, UPB_WELLKNOWN_LISTVALUE)) { start_listvalue_object(p); } else { return false; } - } else if (does_listvalue_start(p)) { + } else if (is_wellknown_field(p, UPB_WELLKNOWN_LISTVALUE)) { if (!start_subobject(p)) return false; start_listvalue_object(p); - } else if (does_value_start(p)) { + } else if (is_wellknown_field(p, UPB_WELLKNOWN_VALUE)) { if (!start_subobject(p)) return false; start_value_object(p, VALUE_LISTVALUE); if (!start_subobject(p)) return false; start_listvalue_object(p); } - UPB_ASSERT(p->top->f); + if (p->top->is_unknown_field) { + inner = p->top + 1; + inner->m = NULL; + inner->name_table = NULL; + inner->f = NULL; + inner->is_map = false; + inner->is_mapentry = false; + inner->is_unknown_field = true; + p->top = inner; + + return true; + } if (!upb_fielddef_isseq(p->top->f)) { upb_status_seterrf(&p->status, @@ -1784,6 +1791,7 @@ static bool start_array(upb_json_parser *p) { inner->f = p->top->f; inner->is_map = false; inner->is_mapentry = false; + inner->is_unknown_field = false; p->top = inner; return true; @@ -1795,17 +1803,22 @@ static void end_array(upb_json_parser *p) { UPB_ASSERT(p->top > p->stack); p->top--; + + if (p->top->is_unknown_field) { + return; + } + sel = getsel_for_handlertype(p, UPB_HANDLER_ENDSEQ); upb_sink_endseq(&p->top->sink, sel); - if (does_listvalue_end(p)) { + if (is_wellknown_msg(p, UPB_WELLKNOWN_LISTVALUE)) { end_listvalue_object(p); if (!is_top_level(p)) { end_subobject(p); } } - if (does_value_end(p)) { + if (is_wellknown_msg(p, UPB_WELLKNOWN_VALUE)) { end_value_object(p); if (!is_top_level(p)) { end_subobject(p); @@ -1814,13 +1827,13 @@ static void end_array(upb_json_parser *p) { } static void start_object(upb_json_parser *p) { - if (!p->top->is_map) { + if (!p->top->is_map && p->top->m != NULL) { upb_sink_startmsg(&p->top->sink); } } static void end_object(upb_json_parser *p) { - if (!p->top->is_map) { + if (!p->top->is_map && p->top->m != NULL) { upb_status status; upb_status_clear(&status); upb_sink_endmsg(&p->top->sink, &status); @@ -1830,54 +1843,10 @@ static void end_object(upb_json_parser *p) { } } -static bool is_double_value(const upb_msgdef *m) { - return strcmp(upb_msgdef_fullname(m), kDoubleValueFullMessageName) == 0; -} - -static bool is_float_value(const upb_msgdef *m) { - return strcmp(upb_msgdef_fullname(m), kFloatValueFullMessageName) == 0; -} - -static bool is_int64_value(const upb_msgdef *m) { - return strcmp(upb_msgdef_fullname(m), kInt64ValueFullMessageName) == 0; -} - -static bool is_uint64_value(const upb_msgdef *m) { - return strcmp(upb_msgdef_fullname(m), kUInt64ValueFullMessageName) == 0; -} - -static bool is_int32_value(const upb_msgdef *m) { - return strcmp(upb_msgdef_fullname(m), kInt32ValueFullMessageName) == 0; -} - -static bool is_uint32_value(const upb_msgdef *m) { - return strcmp(upb_msgdef_fullname(m), kUInt32ValueFullMessageName) == 0; -} - -static bool is_bool_value(const upb_msgdef *m) { - return strcmp(upb_msgdef_fullname(m), kBoolValueFullMessageName) == 0; -} - -static bool is_string_value(const upb_msgdef *m) { - return strcmp(upb_msgdef_fullname(m), kStringValueFullMessageName) == 0; -} - -static bool is_bytes_value(const upb_msgdef *m) { - return strcmp(upb_msgdef_fullname(m), kBytesValueFullMessageName) == 0; -} - -static bool is_number_wrapper(const upb_msgdef *m) { - return is_double_value(m) || - is_float_value(m) || - is_int64_value(m) || - is_uint64_value(m) || - is_int32_value(m) || - is_uint32_value(m); -} - static bool is_string_wrapper(const upb_msgdef *m) { - return is_string_value(m) || - is_bytes_value(m); + upb_wellknowntype_t type = upb_msgdef_wellknowntype(m); + return type == UPB_WELLKNOWN_STRINGVALUE || + type == UPB_WELLKNOWN_BYTESVALUE; } static void start_wrapper_object(upb_json_parser *p) { @@ -1976,21 +1945,32 @@ static void end_structvalue_object(upb_json_parser *p) { } static bool is_top_level(upb_json_parser *p) { - return p->top == p->stack && p->top->f == NULL; + return p->top == p->stack && p->top->f == NULL && !p->top->is_unknown_field; +} + +static bool is_wellknown_msg(upb_json_parser *p, upb_wellknowntype_t type) { + return p->top->m != NULL && upb_msgdef_wellknowntype(p->top->m) == type; +} + +static bool is_wellknown_field(upb_json_parser *p, upb_wellknowntype_t type) { + return p->top->f != NULL && + upb_fielddef_issubmsg(p->top->f) && + (upb_msgdef_wellknowntype(upb_fielddef_msgsubdef(p->top->f)) + == type); } static bool does_number_wrapper_start(upb_json_parser *p) { return p->top->f != NULL && upb_fielddef_issubmsg(p->top->f) && - is_number_wrapper(upb_fielddef_msgsubdef(p->top->f)); + upb_msgdef_isnumberwrapper(upb_fielddef_msgsubdef(p->top->f)); } static bool does_number_wrapper_end(upb_json_parser *p) { - return p->top->m != NULL && is_number_wrapper(p->top->m); + return p->top->m != NULL && upb_msgdef_isnumberwrapper(p->top->m); } static bool is_number_wrapper_object(upb_json_parser *p) { - return p->top->m != NULL && is_number_wrapper(p->top->m); + return p->top->m != NULL && upb_msgdef_isnumberwrapper(p->top->m); } static bool does_string_wrapper_start(upb_json_parser *p) { @@ -2007,91 +1987,6 @@ static bool is_string_wrapper_object(upb_json_parser *p) { return p->top->m != NULL && is_string_wrapper(p->top->m); } -static bool does_boolean_wrapper_start(upb_json_parser *p) { - return p->top->f != NULL && - upb_fielddef_issubmsg(p->top->f) && - is_bool_value(upb_fielddef_msgsubdef(p->top->f)); -} - -static bool does_boolean_wrapper_end(upb_json_parser *p) { - return p->top->m != NULL && is_bool_value(p->top->m); -} - -static bool is_boolean_wrapper_object(upb_json_parser *p) { - return p->top->m != NULL && is_bool_value(p->top->m); -} - -static bool does_duration_start(upb_json_parser *p) { - return p->top->f != NULL && - upb_fielddef_issubmsg(p->top->f) && - upb_msgdef_duration(upb_fielddef_msgsubdef(p->top->f)); -} - -static bool does_duration_end(upb_json_parser *p) { - return p->top->m != NULL && upb_msgdef_duration(p->top->m); -} - -static bool is_duration_object(upb_json_parser *p) { - return p->top->m != NULL && upb_msgdef_duration(p->top->m); -} - -static bool does_timestamp_start(upb_json_parser *p) { - return p->top->f != NULL && - upb_fielddef_issubmsg(p->top->f) && - upb_msgdef_timestamp(upb_fielddef_msgsubdef(p->top->f)); -} - -static bool does_timestamp_end(upb_json_parser *p) { - return p->top->m != NULL && upb_msgdef_timestamp(p->top->m); -} - -static bool is_timestamp_object(upb_json_parser *p) { - return p->top->m != NULL && upb_msgdef_timestamp(p->top->m); -} - -static bool does_value_start(upb_json_parser *p) { - return p->top->f != NULL && - upb_fielddef_issubmsg(p->top->f) && - upb_msgdef_value(upb_fielddef_msgsubdef(p->top->f)); -} - -static bool does_value_end(upb_json_parser *p) { - return p->top->m != NULL && upb_msgdef_value(p->top->m); -} - -static bool is_value_object(upb_json_parser *p) { - return p->top->m != NULL && upb_msgdef_value(p->top->m); -} - -static bool does_listvalue_start(upb_json_parser *p) { - return p->top->f != NULL && - upb_fielddef_issubmsg(p->top->f) && - upb_msgdef_listvalue(upb_fielddef_msgsubdef(p->top->f)); -} - -static bool does_listvalue_end(upb_json_parser *p) { - return p->top->m != NULL && upb_msgdef_listvalue(p->top->m); -} - -static bool is_listvalue_object(upb_json_parser *p) { - return p->top->m != NULL && upb_msgdef_listvalue(p->top->m); -} - -static bool does_structvalue_start(upb_json_parser *p) { - return p->top->f != NULL && - upb_fielddef_issubmsg(p->top->f) && - upb_msgdef_structvalue(upb_fielddef_msgsubdef(p->top->f)); -} - -static bool does_structvalue_end(upb_json_parser *p) { - /* return p->top != p->stack && upb_msgdef_structvalue((p->top - 1)->m); */ - return p->top->m != NULL && upb_msgdef_structvalue(p->top->m); -} - -static bool is_structvalue_object(upb_json_parser *p) { - return p->top->m != NULL && upb_msgdef_structvalue(p->top->m); -} - #define CHECK_RETURN_TOP(x) if (!(x)) goto error @@ -2113,11 +2008,11 @@ static bool is_structvalue_object(upb_json_parser *p) { * final state once, when the closing '"' is seen. */ -#line 2252 "upb/json/parser.rl" +#line 2147 "upb/json/parser.rl" -#line 2121 "upb/json/parser.c" +#line 2016 "upb/json/parser.c" static const char _json_actions[] = { 0, 1, 0, 1, 1, 1, 3, 1, 4, 1, 6, 1, 7, 1, 8, 1, @@ -2368,7 +2263,7 @@ static const int json_en_value_machine = 76; static const int json_en_main = 1; -#line 2255 "upb/json/parser.rl" +#line 2150 "upb/json/parser.rl" size_t parse(void *closure, const void *hd, const char *buf, size_t size, const upb_bufhandle *handle) { @@ -2391,7 +2286,7 @@ size_t parse(void *closure, const void *hd, const char *buf, size_t size, capture_resume(parser, buf); -#line 2395 "upb/json/parser.c" +#line 2290 "upb/json/parser.c" { int _klen; unsigned int _trans; @@ -2466,87 +2361,87 @@ _match: switch ( *_acts++ ) { case 1: -#line 2126 "upb/json/parser.rl" +#line 2021 "upb/json/parser.rl" { p--; {cs = stack[--top]; goto _again;} } break; case 2: -#line 2128 "upb/json/parser.rl" +#line 2023 "upb/json/parser.rl" { p--; {stack[top++] = cs; cs = 24; goto _again;} } break; case 3: -#line 2132 "upb/json/parser.rl" +#line 2027 "upb/json/parser.rl" { start_text(parser, p); } break; case 4: -#line 2133 "upb/json/parser.rl" +#line 2028 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_text(parser, p)); } break; case 5: -#line 2139 "upb/json/parser.rl" +#line 2034 "upb/json/parser.rl" { start_hex(parser); } break; case 6: -#line 2140 "upb/json/parser.rl" +#line 2035 "upb/json/parser.rl" { hexdigit(parser, p); } break; case 7: -#line 2141 "upb/json/parser.rl" +#line 2036 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_hex(parser)); } break; case 8: -#line 2147 "upb/json/parser.rl" +#line 2042 "upb/json/parser.rl" { CHECK_RETURN_TOP(escape(parser, p)); } break; case 9: -#line 2153 "upb/json/parser.rl" +#line 2048 "upb/json/parser.rl" { p--; {cs = stack[--top]; goto _again;} } break; case 10: -#line 2165 "upb/json/parser.rl" +#line 2060 "upb/json/parser.rl" { start_duration_base(parser, p); } break; case 11: -#line 2166 "upb/json/parser.rl" +#line 2061 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_duration_base(parser, p)); } break; case 12: -#line 2168 "upb/json/parser.rl" +#line 2063 "upb/json/parser.rl" { p--; {cs = stack[--top]; goto _again;} } break; case 13: -#line 2173 "upb/json/parser.rl" +#line 2068 "upb/json/parser.rl" { start_timestamp_base(parser, p); } break; case 14: -#line 2174 "upb/json/parser.rl" +#line 2069 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_timestamp_base(parser, p)); } break; case 15: -#line 2176 "upb/json/parser.rl" +#line 2071 "upb/json/parser.rl" { start_timestamp_fraction(parser, p); } break; case 16: -#line 2177 "upb/json/parser.rl" +#line 2072 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_timestamp_fraction(parser, p)); } break; case 17: -#line 2179 "upb/json/parser.rl" +#line 2074 "upb/json/parser.rl" { start_timestamp_zone(parser, p); } break; case 18: -#line 2180 "upb/json/parser.rl" +#line 2075 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_timestamp_zone(parser, p)); } break; case 19: -#line 2182 "upb/json/parser.rl" +#line 2077 "upb/json/parser.rl" { p--; {cs = stack[--top]; goto _again;} } break; case 20: -#line 2187 "upb/json/parser.rl" +#line 2082 "upb/json/parser.rl" { - if (is_timestamp_object(parser)) { + if (is_wellknown_msg(parser, UPB_WELLKNOWN_TIMESTAMP)) { {stack[top++] = cs; cs = 48; goto _again;} - } else if (is_duration_object(parser)) { + } else if (is_wellknown_msg(parser, UPB_WELLKNOWN_DURATION)) { {stack[top++] = cs; cs = 41; goto _again;} } else { {stack[top++] = cs; cs = 33; goto _again;} @@ -2554,78 +2449,78 @@ _match: } break; case 21: -#line 2198 "upb/json/parser.rl" +#line 2093 "upb/json/parser.rl" { p--; {stack[top++] = cs; cs = 76; goto _again;} } break; case 22: -#line 2203 "upb/json/parser.rl" +#line 2098 "upb/json/parser.rl" { start_member(parser); } break; case 23: -#line 2204 "upb/json/parser.rl" +#line 2099 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_membername(parser)); } break; case 24: -#line 2207 "upb/json/parser.rl" +#line 2102 "upb/json/parser.rl" { end_member(parser); } break; case 25: -#line 2213 "upb/json/parser.rl" +#line 2108 "upb/json/parser.rl" { start_object(parser); } break; case 26: -#line 2216 "upb/json/parser.rl" +#line 2111 "upb/json/parser.rl" { end_object(parser); } break; case 27: -#line 2222 "upb/json/parser.rl" +#line 2117 "upb/json/parser.rl" { CHECK_RETURN_TOP(start_array(parser)); } break; case 28: -#line 2226 "upb/json/parser.rl" +#line 2121 "upb/json/parser.rl" { end_array(parser); } break; case 29: -#line 2231 "upb/json/parser.rl" +#line 2126 "upb/json/parser.rl" { CHECK_RETURN_TOP(start_number(parser, p)); } break; case 30: -#line 2232 "upb/json/parser.rl" +#line 2127 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_number(parser, p)); } break; case 31: -#line 2234 "upb/json/parser.rl" +#line 2129 "upb/json/parser.rl" { CHECK_RETURN_TOP(start_stringval(parser)); } break; case 32: -#line 2235 "upb/json/parser.rl" +#line 2130 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_stringval(parser)); } break; case 33: -#line 2237 "upb/json/parser.rl" +#line 2132 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_bool(parser, true)); } break; case 34: -#line 2239 "upb/json/parser.rl" +#line 2134 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_bool(parser, false)); } break; case 35: -#line 2241 "upb/json/parser.rl" +#line 2136 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_null(parser)); } break; case 36: -#line 2243 "upb/json/parser.rl" +#line 2138 "upb/json/parser.rl" { CHECK_RETURN_TOP(start_subobject_full(parser)); } break; case 37: -#line 2244 "upb/json/parser.rl" +#line 2139 "upb/json/parser.rl" { end_subobject_full(parser); } break; case 38: -#line 2249 "upb/json/parser.rl" +#line 2144 "upb/json/parser.rl" { p--; {cs = stack[--top]; goto _again;} } break; -#line 2629 "upb/json/parser.c" +#line 2524 "upb/json/parser.c" } } @@ -2642,34 +2537,34 @@ _again: while ( __nacts-- > 0 ) { switch ( *__acts++ ) { case 0: -#line 2124 "upb/json/parser.rl" +#line 2019 "upb/json/parser.rl" { p--; {cs = stack[--top]; goto _again;} } break; case 26: -#line 2216 "upb/json/parser.rl" +#line 2111 "upb/json/parser.rl" { end_object(parser); } break; case 30: -#line 2232 "upb/json/parser.rl" +#line 2127 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_number(parser, p)); } break; case 33: -#line 2237 "upb/json/parser.rl" +#line 2132 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_bool(parser, true)); } break; case 34: -#line 2239 "upb/json/parser.rl" +#line 2134 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_bool(parser, false)); } break; case 35: -#line 2241 "upb/json/parser.rl" +#line 2136 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_null(parser)); } break; case 37: -#line 2244 "upb/json/parser.rl" +#line 2139 "upb/json/parser.rl" { end_subobject_full(parser); } break; -#line 2673 "upb/json/parser.c" +#line 2568 "upb/json/parser.c" } } } @@ -2677,7 +2572,7 @@ _again: _out: {} } -#line 2277 "upb/json/parser.rl" +#line 2172 "upb/json/parser.rl" if (p != pe) { upb_status_seterrf(&parser->status, "Parse error at '%.*s'\n", pe - p, p); @@ -2709,9 +2604,9 @@ bool end(void *closure, const void *hd) { parse(parser, hd, &eof_ch, 0, NULL); return parser->current_state >= -#line 2713 "upb/json/parser.c" +#line 2608 "upb/json/parser.c" 105 -#line 2307 "upb/json/parser.rl" +#line 2202 "upb/json/parser.rl" ; } @@ -2723,16 +2618,17 @@ static void json_parser_reset(upb_json_parser *p) { p->top->f = NULL; p->top->is_map = false; p->top->is_mapentry = false; + p->top->is_unknown_field = false; /* Emit Ragel initialization of the parser. */ -#line 2730 "upb/json/parser.c" +#line 2626 "upb/json/parser.c" { cs = json_start; top = 0; } -#line 2321 "upb/json/parser.rl" +#line 2217 "upb/json/parser.rl" p->current_state = cs; p->parser_top = top; accumulate_clear(p); diff --git a/upb/json/parser.h b/upb/json/parser.h index 316df0873d..15beaeb987 100644 --- a/upb/json/parser.h +++ b/upb/json/parser.h @@ -29,7 +29,7 @@ UPB_DECLARE_DERIVED_TYPE(upb::json::ParserMethod, upb::RefCounted, * constructed. This hint may be an overestimate for some build configurations. * But if the parser library is upgraded without recompiling the application, * it may be an underestimate. */ -#define UPB_JSON_PARSER_SIZE 4160 +#define UPB_JSON_PARSER_SIZE 4672 #ifdef __cplusplus diff --git a/upb/json/parser.rl b/upb/json/parser.rl index 0ac49a5812..29efd09dae 100644 --- a/upb/json/parser.rl +++ b/upb/json/parser.rl @@ -37,16 +37,6 @@ #define UPB_JSON_MAX_DEPTH 64 -static const char *kDoubleValueFullMessageName = "google.protobuf.DoubleValue"; -static const char *kFloatValueFullMessageName = "google.protobuf.FloatValue"; -static const char *kInt64ValueFullMessageName = "google.protobuf.Int64Value"; -static const char *kUInt64ValueFullMessageName = "google.protobuf.UInt64Value"; -static const char *kInt32ValueFullMessageName = "google.protobuf.Int32Value"; -static const char *kUInt32ValueFullMessageName = "google.protobuf.UInt32Value"; -static const char *kBoolValueFullMessageName = "google.protobuf.BoolValue"; -static const char *kStringValueFullMessageName = "google.protobuf.StringValue"; -static const char *kBytesValueFullMessageName = "google.protobuf.BytesValue"; - /* Type of value message */ enum { VALUE_NULLVALUE = 0, @@ -59,6 +49,8 @@ enum { /* Forward declare */ static bool is_top_level(upb_json_parser *p); +static bool is_wellknown_msg(upb_json_parser *p, upb_wellknowntype_t type); +static bool is_wellknown_field(upb_json_parser *p, upb_wellknowntype_t type); static bool is_number_wrapper_object(upb_json_parser *p); static bool does_number_wrapper_start(upb_json_parser *p); @@ -68,30 +60,6 @@ static bool is_string_wrapper_object(upb_json_parser *p); static bool does_string_wrapper_start(upb_json_parser *p); static bool does_string_wrapper_end(upb_json_parser *p); -static bool is_boolean_wrapper_object(upb_json_parser *p); -static bool does_boolean_wrapper_start(upb_json_parser *p); -static bool does_boolean_wrapper_end(upb_json_parser *p); - -static bool is_duration_object(upb_json_parser *p); -static bool does_duration_start(upb_json_parser *p); -static bool does_duration_end(upb_json_parser *p); - -static bool is_timestamp_object(upb_json_parser *p); -static bool does_timestamp_start(upb_json_parser *p); -static bool does_timestamp_end(upb_json_parser *p); - -static bool is_value_object(upb_json_parser *p); -static bool does_value_start(upb_json_parser *p); -static bool does_value_end(upb_json_parser *p); - -static bool is_listvalue_object(upb_json_parser *p); -static bool does_listvalue_start(upb_json_parser *p); -static bool does_listvalue_end(upb_json_parser *p); - -static bool is_structvalue_object(upb_json_parser *p); -static bool does_structvalue_start(upb_json_parser *p); -static bool does_structvalue_end(upb_json_parser *p); - static void start_wrapper_object(upb_json_parser *p); static void end_wrapper_object(upb_json_parser *p); @@ -143,6 +111,9 @@ typedef struct { * because |f| is the field in the *current* message (i.e., the map-entry * message itself), not the parent's field that leads to this map. */ const upb_fielddef *mapfield; + + /* True if the field to be parsed is unknown. */ + bool is_unknown_field; } upb_jsonparser_frame; struct upb_json_parser { @@ -699,7 +670,7 @@ static bool start_number(upb_json_parser *p, const char *ptr) { if (is_top_level(p)) { if (is_number_wrapper_object(p)) { start_wrapper_object(p); - } else if (is_value_object(p)) { + } else if (is_wellknown_msg(p, UPB_WELLKNOWN_VALUE)) { start_value_object(p, VALUE_NUMBERVALUE); } else { return false; @@ -709,7 +680,7 @@ static bool start_number(upb_json_parser *p, const char *ptr) { return false; } start_wrapper_object(p); - } else if (does_value_start(p)) { + } else if (is_wellknown_field(p, UPB_WELLKNOWN_VALUE)) { if (!start_subobject(p)) { return false; } @@ -749,7 +720,7 @@ static bool end_number(upb_json_parser *p, const char *ptr) { return true; } - if (does_value_end(p)) { + if (is_wellknown_msg(p, UPB_WELLKNOWN_VALUE)) { end_value_object(p); if (!is_top_level(p)) { end_subobject(p); @@ -929,30 +900,34 @@ static bool parser_putbool(upb_json_parser *p, bool val) { static bool end_bool(upb_json_parser *p, bool val) { if (is_top_level(p)) { - if (is_boolean_wrapper_object(p)) { + if (is_wellknown_msg(p, UPB_WELLKNOWN_BOOLVALUE)) { start_wrapper_object(p); - } else if (is_value_object(p)) { + } else if (is_wellknown_msg(p, UPB_WELLKNOWN_VALUE)) { start_value_object(p, VALUE_BOOLVALUE); } else { return false; } - } else if (does_boolean_wrapper_start(p)) { + } else if (is_wellknown_field(p, UPB_WELLKNOWN_BOOLVALUE)) { if (!start_subobject(p)) { return false; } start_wrapper_object(p); - } else if (does_value_start(p)) { + } else if (is_wellknown_field(p, UPB_WELLKNOWN_VALUE)) { if (!start_subobject(p)) { return false; } start_value_object(p, VALUE_BOOLVALUE); } + if (p->top->is_unknown_field) { + return true; + } + if (!parser_putbool(p, val)) { return false; } - if (does_boolean_wrapper_end(p)) { + if (is_wellknown_msg(p, UPB_WELLKNOWN_BOOLVALUE)) { end_wrapper_object(p); if (!is_top_level(p)) { end_subobject(p); @@ -960,7 +935,7 @@ static bool end_bool(upb_json_parser *p, bool val) { return true; } - if (does_value_end(p)) { + if (is_wellknown_msg(p, UPB_WELLKNOWN_VALUE)) { end_value_object(p); if (!is_top_level(p)) { end_subobject(p); @@ -975,12 +950,12 @@ static bool end_null(upb_json_parser *p) { const char *zero_ptr = "0"; if (is_top_level(p)) { - if (is_value_object(p)) { + if (is_wellknown_msg(p, UPB_WELLKNOWN_VALUE)) { start_value_object(p, VALUE_NULLVALUE); } else { return true; } - } else if (does_value_start(p)) { + } else if (is_wellknown_field(p, UPB_WELLKNOWN_VALUE)) { if (!start_subobject(p)) { return false; } @@ -1007,9 +982,10 @@ static bool start_stringval(upb_json_parser *p) { if (is_top_level(p)) { if (is_string_wrapper_object(p)) { start_wrapper_object(p); - } else if (is_timestamp_object(p) || is_duration_object(p)) { + } else if (is_wellknown_msg(p, UPB_WELLKNOWN_TIMESTAMP) || + is_wellknown_msg(p, UPB_WELLKNOWN_DURATION)) { start_object(p); - } else if (is_value_object(p)) { + } else if (is_wellknown_msg(p, UPB_WELLKNOWN_VALUE)) { start_value_object(p, VALUE_STRINGVALUE); } else { return false; @@ -1019,12 +995,13 @@ static bool start_stringval(upb_json_parser *p) { return false; } start_wrapper_object(p); - } else if (does_timestamp_start(p) || does_duration_start(p)) { + } else if (is_wellknown_field(p, UPB_WELLKNOWN_TIMESTAMP) || + is_wellknown_field(p, UPB_WELLKNOWN_DURATION)) { if (!start_subobject(p)) { return false; } start_object(p); - } else if (does_value_start(p)) { + } else if (is_wellknown_field(p, UPB_WELLKNOWN_VALUE)) { if (!start_subobject(p)) { return false; } @@ -1052,6 +1029,7 @@ static bool start_stringval(upb_json_parser *p) { inner->name_table = NULL; inner->is_map = false; inner->is_mapentry = false; + inner->is_unknown_field = false; p->top = inner; if (upb_fielddef_type(p->top->f) == UPB_TYPE_STRING) { @@ -1085,7 +1063,8 @@ static bool start_stringval(upb_json_parser *p) { static bool end_stringval_nontop(upb_json_parser *p) { bool ok = true; - if (is_timestamp_object(p) || is_duration_object(p)) { + if (is_wellknown_msg(p, UPB_WELLKNOWN_TIMESTAMP) || + is_wellknown_msg(p, UPB_WELLKNOWN_DURATION)) { multipart_end(p); return true; } @@ -1167,7 +1146,7 @@ static bool end_stringval(upb_json_parser *p) { return true; } - if (does_value_end(p)) { + if (is_wellknown_msg(p, UPB_WELLKNOWN_VALUE)) { end_value_object(p); if (!is_top_level(p)) { end_subobject(p); @@ -1175,7 +1154,8 @@ static bool end_stringval(upb_json_parser *p) { return true; } - if (does_timestamp_end(p) || does_duration_end(p)) { + if (is_wellknown_msg(p, UPB_WELLKNOWN_TIMESTAMP) || + is_wellknown_msg(p, UPB_WELLKNOWN_DURATION)) { end_object(p); if (!is_top_level(p)) { end_subobject(p); @@ -1287,18 +1267,26 @@ static void start_timestamp_base(upb_json_parser *p, const char *ptr) { capture_begin(p, ptr); } +#define UPB_TIMESTAMP_BASE_SIZE 19 + static bool end_timestamp_base(upb_json_parser *p, const char *ptr) { size_t len; const char *buf; + /* 3 for GMT and 1 for ending 0 */ + char timestamp_buf[UPB_TIMESTAMP_BASE_SIZE + 4]; if (!capture_end(p, ptr)) { return false; } buf = accumulate_getptr(p, &len); + UPB_ASSERT(len == UPB_TIMESTAMP_BASE_SIZE); + memcpy(timestamp_buf, buf, UPB_TIMESTAMP_BASE_SIZE); + memcpy(timestamp_buf + UPB_TIMESTAMP_BASE_SIZE, "GMT", 3); + timestamp_buf[UPB_TIMESTAMP_BASE_SIZE + 3] = 0; /* Parse seconds */ - if (strptime(buf, "%FT%H:%M:%S", &p->tm) == NULL) { + if (strptime(timestamp_buf, "%FT%H:%M:%S%Z", &p->tm) == NULL) { upb_status_seterrf(&p->status, "error parsing timestamp: %s", buf); upb_env_reporterror(p->env, &p->status); return false; @@ -1533,6 +1521,7 @@ static bool handle_mapentry(upb_json_parser *p) { inner->name_table = NULL; inner->mapfield = mapfield; inner->is_map = false; + inner->is_unknown_field = false; /* Don't set this to true *yet* -- we reuse parsing handlers below to push * the key field value to the sink, and these handlers will pop the frame @@ -1563,6 +1552,8 @@ static bool end_membername(upb_json_parser *p) { UPB_ASSERT(!p->top->f); if (!p->top->m) { + p->top->is_unknown_field = true; + multipart_end(p); return true; } @@ -1579,6 +1570,7 @@ static bool end_membername(upb_json_parser *p) { return true; } else if (p->ignore_json_unknown) { + p->top->is_unknown_field = true; multipart_end(p); return true; } else { @@ -1610,10 +1602,11 @@ static void end_member(upb_json_parser *p) { } p->top->f = NULL; + p->top->is_unknown_field = false; } static bool start_subobject(upb_json_parser *p) { - if (p->top->f == NULL) { + if (p->top->is_unknown_field) { upb_jsonparser_frame *inner; if (!check_stack(p)) return false; @@ -1622,6 +1615,7 @@ static bool start_subobject(upb_json_parser *p) { inner->f = NULL; inner->is_map = false; inner->is_mapentry = false; + inner->is_unknown_field = false; p->top = inner; return true; } @@ -1643,6 +1637,7 @@ static bool start_subobject(upb_json_parser *p) { inner->f = NULL; inner->is_map = true; inner->is_mapentry = false; + inner->is_unknown_field = false; p->top = inner; return true; @@ -1663,6 +1658,7 @@ static bool start_subobject(upb_json_parser *p) { inner->f = NULL; inner->is_map = false; inner->is_mapentry = false; + inner->is_unknown_field = false; p->top = inner; return true; @@ -1677,19 +1673,19 @@ static bool start_subobject(upb_json_parser *p) { static bool start_subobject_full(upb_json_parser *p) { if (is_top_level(p)) { - if (is_value_object(p)) { + if (is_wellknown_msg(p, UPB_WELLKNOWN_VALUE)) { start_value_object(p, VALUE_STRUCTVALUE); if (!start_subobject(p)) return false; start_structvalue_object(p); - } else if (is_structvalue_object(p)) { + } else if (is_wellknown_msg(p, UPB_WELLKNOWN_STRUCT)) { start_structvalue_object(p); } else { return true; } - } else if (does_structvalue_start(p)) { + } else if (is_wellknown_field(p, UPB_WELLKNOWN_STRUCT)) { if (!start_subobject(p)) return false; start_structvalue_object(p); - } else if (does_value_start(p)) { + } else if (is_wellknown_field(p, UPB_WELLKNOWN_VALUE)) { if (!start_subobject(p)) return false; start_value_object(p, VALUE_STRUCTVALUE); if (!start_subobject(p)) return false; @@ -1723,14 +1719,14 @@ static void end_subobject(upb_json_parser *p) { static void end_subobject_full(upb_json_parser *p) { end_subobject(p); - if (does_structvalue_end(p)) { + if (is_wellknown_msg(p, UPB_WELLKNOWN_STRUCT)) { end_structvalue_object(p); if (!is_top_level(p)) { end_subobject(p); } } - if (does_value_end(p)) { + if (is_wellknown_msg(p, UPB_WELLKNOWN_VALUE)) { end_value_object(p); if (!is_top_level(p)) { end_subobject(p); @@ -1743,26 +1739,37 @@ static bool start_array(upb_json_parser *p) { upb_selector_t sel; if (is_top_level(p)) { - if (is_value_object(p)) { + if (is_wellknown_msg(p, UPB_WELLKNOWN_VALUE)) { start_value_object(p, VALUE_LISTVALUE); if (!start_subobject(p)) return false; start_listvalue_object(p); - } else if (is_listvalue_object(p)) { + } else if (is_wellknown_msg(p, UPB_WELLKNOWN_LISTVALUE)) { start_listvalue_object(p); } else { return false; } - } else if (does_listvalue_start(p)) { + } else if (is_wellknown_field(p, UPB_WELLKNOWN_LISTVALUE)) { if (!start_subobject(p)) return false; start_listvalue_object(p); - } else if (does_value_start(p)) { + } else if (is_wellknown_field(p, UPB_WELLKNOWN_VALUE)) { if (!start_subobject(p)) return false; start_value_object(p, VALUE_LISTVALUE); if (!start_subobject(p)) return false; start_listvalue_object(p); } - UPB_ASSERT(p->top->f); + if (p->top->is_unknown_field) { + inner = p->top + 1; + inner->m = NULL; + inner->name_table = NULL; + inner->f = NULL; + inner->is_map = false; + inner->is_mapentry = false; + inner->is_unknown_field = true; + p->top = inner; + + return true; + } if (!upb_fielddef_isseq(p->top->f)) { upb_status_seterrf(&p->status, @@ -1782,6 +1789,7 @@ static bool start_array(upb_json_parser *p) { inner->f = p->top->f; inner->is_map = false; inner->is_mapentry = false; + inner->is_unknown_field = false; p->top = inner; return true; @@ -1793,17 +1801,22 @@ static void end_array(upb_json_parser *p) { UPB_ASSERT(p->top > p->stack); p->top--; + + if (p->top->is_unknown_field) { + return; + } + sel = getsel_for_handlertype(p, UPB_HANDLER_ENDSEQ); upb_sink_endseq(&p->top->sink, sel); - if (does_listvalue_end(p)) { + if (is_wellknown_msg(p, UPB_WELLKNOWN_LISTVALUE)) { end_listvalue_object(p); if (!is_top_level(p)) { end_subobject(p); } } - if (does_value_end(p)) { + if (is_wellknown_msg(p, UPB_WELLKNOWN_VALUE)) { end_value_object(p); if (!is_top_level(p)) { end_subobject(p); @@ -1812,13 +1825,13 @@ static void end_array(upb_json_parser *p) { } static void start_object(upb_json_parser *p) { - if (!p->top->is_map) { + if (!p->top->is_map && p->top->m != NULL) { upb_sink_startmsg(&p->top->sink); } } static void end_object(upb_json_parser *p) { - if (!p->top->is_map) { + if (!p->top->is_map && p->top->m != NULL) { upb_status status; upb_status_clear(&status); upb_sink_endmsg(&p->top->sink, &status); @@ -1828,54 +1841,10 @@ static void end_object(upb_json_parser *p) { } } -static bool is_double_value(const upb_msgdef *m) { - return strcmp(upb_msgdef_fullname(m), kDoubleValueFullMessageName) == 0; -} - -static bool is_float_value(const upb_msgdef *m) { - return strcmp(upb_msgdef_fullname(m), kFloatValueFullMessageName) == 0; -} - -static bool is_int64_value(const upb_msgdef *m) { - return strcmp(upb_msgdef_fullname(m), kInt64ValueFullMessageName) == 0; -} - -static bool is_uint64_value(const upb_msgdef *m) { - return strcmp(upb_msgdef_fullname(m), kUInt64ValueFullMessageName) == 0; -} - -static bool is_int32_value(const upb_msgdef *m) { - return strcmp(upb_msgdef_fullname(m), kInt32ValueFullMessageName) == 0; -} - -static bool is_uint32_value(const upb_msgdef *m) { - return strcmp(upb_msgdef_fullname(m), kUInt32ValueFullMessageName) == 0; -} - -static bool is_bool_value(const upb_msgdef *m) { - return strcmp(upb_msgdef_fullname(m), kBoolValueFullMessageName) == 0; -} - -static bool is_string_value(const upb_msgdef *m) { - return strcmp(upb_msgdef_fullname(m), kStringValueFullMessageName) == 0; -} - -static bool is_bytes_value(const upb_msgdef *m) { - return strcmp(upb_msgdef_fullname(m), kBytesValueFullMessageName) == 0; -} - -static bool is_number_wrapper(const upb_msgdef *m) { - return is_double_value(m) || - is_float_value(m) || - is_int64_value(m) || - is_uint64_value(m) || - is_int32_value(m) || - is_uint32_value(m); -} - static bool is_string_wrapper(const upb_msgdef *m) { - return is_string_value(m) || - is_bytes_value(m); + upb_wellknowntype_t type = upb_msgdef_wellknowntype(m); + return type == UPB_WELLKNOWN_STRINGVALUE || + type == UPB_WELLKNOWN_BYTESVALUE; } static void start_wrapper_object(upb_json_parser *p) { @@ -1974,21 +1943,32 @@ static void end_structvalue_object(upb_json_parser *p) { } static bool is_top_level(upb_json_parser *p) { - return p->top == p->stack && p->top->f == NULL; + return p->top == p->stack && p->top->f == NULL && !p->top->is_unknown_field; +} + +static bool is_wellknown_msg(upb_json_parser *p, upb_wellknowntype_t type) { + return p->top->m != NULL && upb_msgdef_wellknowntype(p->top->m) == type; +} + +static bool is_wellknown_field(upb_json_parser *p, upb_wellknowntype_t type) { + return p->top->f != NULL && + upb_fielddef_issubmsg(p->top->f) && + (upb_msgdef_wellknowntype(upb_fielddef_msgsubdef(p->top->f)) + == type); } static bool does_number_wrapper_start(upb_json_parser *p) { return p->top->f != NULL && upb_fielddef_issubmsg(p->top->f) && - is_number_wrapper(upb_fielddef_msgsubdef(p->top->f)); + upb_msgdef_isnumberwrapper(upb_fielddef_msgsubdef(p->top->f)); } static bool does_number_wrapper_end(upb_json_parser *p) { - return p->top->m != NULL && is_number_wrapper(p->top->m); + return p->top->m != NULL && upb_msgdef_isnumberwrapper(p->top->m); } static bool is_number_wrapper_object(upb_json_parser *p) { - return p->top->m != NULL && is_number_wrapper(p->top->m); + return p->top->m != NULL && upb_msgdef_isnumberwrapper(p->top->m); } static bool does_string_wrapper_start(upb_json_parser *p) { @@ -2005,91 +1985,6 @@ static bool is_string_wrapper_object(upb_json_parser *p) { return p->top->m != NULL && is_string_wrapper(p->top->m); } -static bool does_boolean_wrapper_start(upb_json_parser *p) { - return p->top->f != NULL && - upb_fielddef_issubmsg(p->top->f) && - is_bool_value(upb_fielddef_msgsubdef(p->top->f)); -} - -static bool does_boolean_wrapper_end(upb_json_parser *p) { - return p->top->m != NULL && is_bool_value(p->top->m); -} - -static bool is_boolean_wrapper_object(upb_json_parser *p) { - return p->top->m != NULL && is_bool_value(p->top->m); -} - -static bool does_duration_start(upb_json_parser *p) { - return p->top->f != NULL && - upb_fielddef_issubmsg(p->top->f) && - upb_msgdef_duration(upb_fielddef_msgsubdef(p->top->f)); -} - -static bool does_duration_end(upb_json_parser *p) { - return p->top->m != NULL && upb_msgdef_duration(p->top->m); -} - -static bool is_duration_object(upb_json_parser *p) { - return p->top->m != NULL && upb_msgdef_duration(p->top->m); -} - -static bool does_timestamp_start(upb_json_parser *p) { - return p->top->f != NULL && - upb_fielddef_issubmsg(p->top->f) && - upb_msgdef_timestamp(upb_fielddef_msgsubdef(p->top->f)); -} - -static bool does_timestamp_end(upb_json_parser *p) { - return p->top->m != NULL && upb_msgdef_timestamp(p->top->m); -} - -static bool is_timestamp_object(upb_json_parser *p) { - return p->top->m != NULL && upb_msgdef_timestamp(p->top->m); -} - -static bool does_value_start(upb_json_parser *p) { - return p->top->f != NULL && - upb_fielddef_issubmsg(p->top->f) && - upb_msgdef_value(upb_fielddef_msgsubdef(p->top->f)); -} - -static bool does_value_end(upb_json_parser *p) { - return p->top->m != NULL && upb_msgdef_value(p->top->m); -} - -static bool is_value_object(upb_json_parser *p) { - return p->top->m != NULL && upb_msgdef_value(p->top->m); -} - -static bool does_listvalue_start(upb_json_parser *p) { - return p->top->f != NULL && - upb_fielddef_issubmsg(p->top->f) && - upb_msgdef_listvalue(upb_fielddef_msgsubdef(p->top->f)); -} - -static bool does_listvalue_end(upb_json_parser *p) { - return p->top->m != NULL && upb_msgdef_listvalue(p->top->m); -} - -static bool is_listvalue_object(upb_json_parser *p) { - return p->top->m != NULL && upb_msgdef_listvalue(p->top->m); -} - -static bool does_structvalue_start(upb_json_parser *p) { - return p->top->f != NULL && - upb_fielddef_issubmsg(p->top->f) && - upb_msgdef_structvalue(upb_fielddef_msgsubdef(p->top->f)); -} - -static bool does_structvalue_end(upb_json_parser *p) { - /* return p->top != p->stack && upb_msgdef_structvalue((p->top - 1)->m); */ - return p->top->m != NULL && upb_msgdef_structvalue(p->top->m); -} - -static bool is_structvalue_object(upb_json_parser *p) { - return p->top->m != NULL && upb_msgdef_structvalue(p->top->m); -} - #define CHECK_RETURN_TOP(x) if (!(x)) goto error @@ -2185,9 +2080,9 @@ static bool is_structvalue_object(upb_json_parser *p) { string = '"' @{ - if (is_timestamp_object(parser)) { + if (is_wellknown_msg(parser, UPB_WELLKNOWN_TIMESTAMP)) { fcall timestamp_machine; - } else if (is_duration_object(parser)) { + } else if (is_wellknown_msg(parser, UPB_WELLKNOWN_DURATION)) { fcall duration_machine; } else { fcall string_machine; @@ -2315,6 +2210,7 @@ static void json_parser_reset(upb_json_parser *p) { p->top->f = NULL; p->top->is_map = false; p->top->is_mapentry = false; + p->top->is_unknown_field = false; /* Emit Ragel initialization of the parser. */ %% write init; diff --git a/upb/json/printer.c b/upb/json/printer.c index a3803a1761..edffa3b570 100644 --- a/upb/json/printer.c +++ b/upb/json/printer.c @@ -708,6 +708,54 @@ static bool putnanos(void *closure, const void *handler_data, return true; } +static void *scalar_startstr_nokey(void *closure, const void *handler_data, + size_t size_hint) { + upb_json_printer *p = closure; + UPB_UNUSED(handler_data); + UPB_UNUSED(size_hint); + print_data(p, "\"", 1); + return p; +} + +static size_t putstr_nokey(void *closure, const void *handler_data, + const char *str, size_t len, + const upb_bufhandle *handle) { + upb_json_printer *p = closure; + UPB_UNUSED(handler_data); + UPB_UNUSED(handle); + print_data(p, "\"", 1); + putstring(p, str, len); + print_data(p, "\"", 1); + return len + 2; +} + +static void *startseq_nokey(void *closure, const void *handler_data) { + upb_json_printer *p = closure; + UPB_UNUSED(handler_data); + p->depth_++; + p->first_elem_[p->depth_] = true; + print_data(p, "[", 1); + return closure; +} + +static void *startmap_nokey(void *closure, const void *handler_data) { + upb_json_printer *p = closure; + UPB_UNUSED(handler_data); + p->depth_++; + p->first_elem_[p->depth_] = true; + print_data(p, "{", 1); + return closure; +} + +static bool putnull(void *closure, const void *handler_data, + int32_t null) { + upb_json_printer *p = closure; + print_data(p, "null", 4); + UPB_UNUSED(handler_data); + UPB_UNUSED(null); + return true; +} + static bool printer_startdurationmsg(void *closure, const void *handler_data) { upb_json_printer *p = closure; UPB_UNUSED(handler_data); @@ -852,6 +900,26 @@ static bool printer_endtimestampmsg(void *closure, const void *handler_data, return true; } +static bool printer_startmsg_noframe(void *closure, const void *handler_data) { + upb_json_printer *p = closure; + UPB_UNUSED(handler_data); + if (p->depth_ == 0) { + upb_bytessink_start(p->output_, 0, &p->subc_); + } + return true; +} + +static bool printer_endmsg_noframe( + void *closure, const void *handler_data, upb_status *s) { + upb_json_printer *p = closure; + UPB_UNUSED(handler_data); + UPB_UNUSED(s); + if (p->depth_ == 0) { + upb_bytessink_end(p->output_); + } + return true; +} + /* Set up handlers for a duration submessage. */ void printer_sethandlers_duration(const void *closure, upb_handlers *h) { const upb_msgdef *md = upb_handlers_msgdef(h); @@ -891,6 +959,102 @@ void printer_sethandlers_timestamp(const void *closure, upb_handlers *h) { UPB_UNUSED(closure); } +void printer_sethandlers_value(const void *closure, upb_handlers *h) { + const upb_msgdef *md = upb_handlers_msgdef(h); + upb_msg_field_iter i; + + upb_handlerattr empty_attr = UPB_HANDLERATTR_INITIALIZER; + + upb_handlers_setstartmsg(h, printer_startmsg_noframe, &empty_attr); + upb_handlers_setendmsg(h, printer_endmsg_noframe, &empty_attr); + + upb_msg_field_begin(&i, md); + for(; !upb_msg_field_done(&i); upb_msg_field_next(&i)) { + const upb_fielddef *f = upb_msg_iter_field(&i); + + switch (upb_fielddef_type(f)) { + case UPB_TYPE_ENUM: + upb_handlers_setint32(h, f, putnull, &empty_attr); + break; + case UPB_TYPE_DOUBLE: + upb_handlers_setdouble(h, f, putdouble, &empty_attr); + break; + case UPB_TYPE_STRING: + upb_handlers_setstartstr(h, f, scalar_startstr_nokey, &empty_attr); + upb_handlers_setstring(h, f, scalar_str, &empty_attr); + upb_handlers_setendstr(h, f, scalar_endstr, &empty_attr); + break; + case UPB_TYPE_BOOL: + upb_handlers_setbool(h, f, putbool, &empty_attr); + break; + case UPB_TYPE_MESSAGE: + break; + default: + UPB_ASSERT(false); + break; + } + } + + UPB_UNUSED(closure); +} + +#define WRAPPER_SETHANDLERS(wrapper, type, putmethod) \ +void printer_sethandlers_##wrapper(const void *closure, upb_handlers *h) { \ + const upb_msgdef *md = upb_handlers_msgdef(h); \ + const upb_fielddef* f = upb_msgdef_itof(md, 1); \ + upb_handlerattr empty_attr = UPB_HANDLERATTR_INITIALIZER; \ + upb_handlers_setstartmsg(h, printer_startmsg_noframe, &empty_attr); \ + upb_handlers_setendmsg(h, printer_endmsg_noframe, &empty_attr); \ + upb_handlers_set##type(h, f, putmethod, &empty_attr); \ + UPB_UNUSED(closure); \ +} + +WRAPPER_SETHANDLERS(doublevalue, double, putdouble) +WRAPPER_SETHANDLERS(floatvalue, float, putfloat) +WRAPPER_SETHANDLERS(int64value, int64, putint64_t) +WRAPPER_SETHANDLERS(uint64value, uint64, putuint64_t) +WRAPPER_SETHANDLERS(int32value, int32, putint32_t) +WRAPPER_SETHANDLERS(uint32value, uint32, putuint32_t) +WRAPPER_SETHANDLERS(boolvalue, bool, putbool) +WRAPPER_SETHANDLERS(stringvalue, string, putstr_nokey) +WRAPPER_SETHANDLERS(bytesvalue, string, putbytes) + +#undef WRAPPER_SETHANDLERS + +void printer_sethandlers_listvalue(const void *closure, upb_handlers *h) { + const upb_msgdef *md = upb_handlers_msgdef(h); + const upb_fielddef* f = upb_msgdef_itof(md, 1); + + upb_handlerattr empty_attr = UPB_HANDLERATTR_INITIALIZER; + + upb_handlers_setstartseq(h, f, startseq_nokey, &empty_attr); + upb_handlers_setendseq(h, f, endseq, &empty_attr); + + upb_handlers_setstartmsg(h, printer_startmsg_noframe, &empty_attr); + upb_handlers_setendmsg(h, printer_endmsg_noframe, &empty_attr); + + upb_handlers_setstartsubmsg(h, f, repeated_startsubmsg, &empty_attr); + + UPB_UNUSED(closure); +} + +void printer_sethandlers_structvalue(const void *closure, upb_handlers *h) { + const upb_msgdef *md = upb_handlers_msgdef(h); + const upb_fielddef* f = upb_msgdef_itof(md, 1); + + upb_handlerattr empty_attr = UPB_HANDLERATTR_INITIALIZER; + + upb_handlers_setstartseq(h, f, startmap_nokey, &empty_attr); + upb_handlers_setendseq(h, f, endmap, &empty_attr); + + upb_handlers_setstartmsg(h, printer_startmsg_noframe, &empty_attr); + upb_handlers_setendmsg(h, printer_endmsg_noframe, &empty_attr); + + upb_handlers_setstartsubmsg(h, f, repeated_startsubmsg, &empty_attr); + + UPB_UNUSED(closure); +} + void printer_sethandlers(const void *closure, upb_handlers *h) { const upb_msgdef *md = upb_handlers_msgdef(h); bool is_mapentry = upb_msgdef_mapentry(md); @@ -906,14 +1070,40 @@ void printer_sethandlers(const void *closure, upb_handlers *h) { return; } - if (upb_msgdef_duration(md)) { - printer_sethandlers_duration(closure, h); - return; - } - - if (upb_msgdef_timestamp(md)) { - printer_sethandlers_timestamp(closure, h); - return; + switch (upb_msgdef_wellknowntype(md)) { + case UPB_WELLKNOWN_UNSPECIFIED: + break; + case UPB_WELLKNOWN_DURATION: + printer_sethandlers_duration(closure, h); + return; + case UPB_WELLKNOWN_TIMESTAMP: + printer_sethandlers_timestamp(closure, h); + return; + case UPB_WELLKNOWN_VALUE: + printer_sethandlers_value(closure, h); + return; + case UPB_WELLKNOWN_LISTVALUE: + printer_sethandlers_listvalue(closure, h); + return; + case UPB_WELLKNOWN_STRUCT: + printer_sethandlers_structvalue(closure, h); + return; +#define WRAPPER(wellknowntype, name) \ + case wellknowntype: \ + printer_sethandlers_##name(closure, h); \ + return; \ + + WRAPPER(UPB_WELLKNOWN_DOUBLEVALUE, doublevalue); + WRAPPER(UPB_WELLKNOWN_FLOATVALUE, floatvalue); + WRAPPER(UPB_WELLKNOWN_INT64VALUE, int64value); + WRAPPER(UPB_WELLKNOWN_UINT64VALUE, uint64value); + WRAPPER(UPB_WELLKNOWN_INT32VALUE, int32value); + WRAPPER(UPB_WELLKNOWN_UINT32VALUE, uint32value); + WRAPPER(UPB_WELLKNOWN_BOOLVALUE, boolvalue); + WRAPPER(UPB_WELLKNOWN_STRINGVALUE, stringvalue); + WRAPPER(UPB_WELLKNOWN_BYTESVALUE, bytesvalue); + +#undef WRAPPER } upb_handlers_setstartmsg(h, printer_startmsg, &empty_attr); diff --git a/upb/structdefs.int.h b/upb/structdefs.int.h new file mode 100644 index 0000000000..cf8bd1d385 --- /dev/null +++ b/upb/structdefs.int.h @@ -0,0 +1,196 @@ +/* +** This file contains definitions of structs that should be considered private +** and NOT stable across versions of upb. +** +** The only reason they are declared here and not in .c files is to allow upb +** and the application (if desired) to embed statically-initialized instances +** of structures like defs. +** +** If you include this file, all guarantees of ABI compatibility go out the +** window! Any code that includes this file needs to recompile against the +** exact same version of upb that they are linking against. +** +** You also need to recompile if you change the value of the UPB_DEBUG_REFS +** flag. +*/ + +#include "upb/def.h" + +#ifndef UPB_STATICINIT_H_ +#define UPB_STATICINIT_H_ + +#ifdef __cplusplus +/* Because of how we do our typedefs, this header can't be included from C++. */ +#error This file cannot be included from C++ +#endif + +/* upb_refcounted *************************************************************/ + + +/* upb_def ********************************************************************/ + +struct upb_def { + upb_refcounted base; + + const char *fullname; + const upb_filedef* file; + char type; /* A upb_deftype_t (char to save space) */ + + /* Used as a flag during the def's mutable stage. Must be false unless + * it is currently being used by a function on the stack. This allows + * us to easily determine which defs were passed into the function's + * current invocation. */ + bool came_from_user; +}; + +#define UPB_DEF_INIT(name, type, vtbl, refs, ref2s) \ + { UPB_REFCOUNT_INIT(vtbl, refs, ref2s), name, NULL, type, false } + + +/* upb_fielddef ***************************************************************/ + +struct upb_fielddef { + upb_def base; + + union { + int64_t sint; + uint64_t uint; + double dbl; + float flt; + void *bytes; + } defaultval; + union { + const upb_msgdef *def; /* If !msg_is_symbolic. */ + char *name; /* If msg_is_symbolic. */ + } msg; + union { + const upb_def *def; /* If !subdef_is_symbolic. */ + char *name; /* If subdef_is_symbolic. */ + } sub; /* The msgdef or enumdef for this field, if upb_hassubdef(f). */ + bool subdef_is_symbolic; + bool msg_is_symbolic; + const upb_oneofdef *oneof; + bool default_is_string; + bool type_is_set_; /* False until type is explicitly set. */ + bool is_extension_; + bool lazy_; + bool packed_; + upb_intfmt_t intfmt; + bool tagdelim; + upb_fieldtype_t type_; + upb_label_t label_; + uint32_t number_; + uint32_t selector_base; /* Used to index into a upb::Handlers table. */ + uint32_t index_; +}; + +extern const struct upb_refcounted_vtbl upb_fielddef_vtbl; + +#define UPB_FIELDDEF_INIT(label, type, intfmt, tagdelim, is_extension, lazy, \ + packed, name, num, msgdef, subdef, selector_base, \ + index, defaultval, refs, ref2s) \ + { \ + UPB_DEF_INIT(name, UPB_DEF_FIELD, &upb_fielddef_vtbl, refs, ref2s), \ + defaultval, {msgdef}, {subdef}, NULL, false, false, \ + type == UPB_TYPE_STRING || type == UPB_TYPE_BYTES, true, is_extension, \ + lazy, packed, intfmt, tagdelim, type, label, num, selector_base, index \ + } + + +/* upb_msgdef *****************************************************************/ + +struct upb_msgdef { + upb_def base; + + size_t selector_count; + uint32_t submsg_field_count; + + /* Tables for looking up fields by number and name. */ + upb_inttable itof; /* int to field */ + upb_strtable ntof; /* name to field/oneof */ + + /* Is this a map-entry message? */ + bool map_entry; + + /* Whether this message has proto2 or proto3 semantics. */ + upb_syntax_t syntax; + + /* Type of well known type message. UPB_WELLKNOWN_UNSPECIFIED for + * non-well-known message. */ + upb_wellknowntype_t well_known_type; + + /* TODO(haberman): proper extension ranges (there can be multiple). */ +}; + +extern const struct upb_refcounted_vtbl upb_msgdef_vtbl; + +/* TODO: also support static initialization of the oneofs table. This will be + * needed if we compile in descriptors that contain oneofs. */ +#define UPB_MSGDEF_INIT(name, selector_count, submsg_field_count, itof, ntof, \ + map_entry, syntax, well_known_type, refs, ref2s) \ + { \ + UPB_DEF_INIT(name, UPB_DEF_MSG, &upb_fielddef_vtbl, refs, ref2s), \ + selector_count, submsg_field_count, itof, ntof, map_entry, syntax, \ + well_known_type \ + } + + +/* upb_enumdef ****************************************************************/ + +struct upb_enumdef { + upb_def base; + + upb_strtable ntoi; + upb_inttable iton; + int32_t defaultval; +}; + +extern const struct upb_refcounted_vtbl upb_enumdef_vtbl; + +#define UPB_ENUMDEF_INIT(name, ntoi, iton, defaultval, refs, ref2s) \ + { UPB_DEF_INIT(name, UPB_DEF_ENUM, &upb_enumdef_vtbl, refs, ref2s), ntoi, \ + iton, defaultval } + + +/* upb_oneofdef ***************************************************************/ + +struct upb_oneofdef { + upb_refcounted base; + + uint32_t index; /* Index within oneofs. */ + const char *name; + upb_strtable ntof; + upb_inttable itof; + const upb_msgdef *parent; +}; + +extern const struct upb_refcounted_vtbl upb_oneofdef_vtbl; + +#define UPB_ONEOFDEF_INIT(name, ntof, itof, refs, ref2s) \ + { UPB_REFCOUNT_INIT(&upb_oneofdef_vtbl, refs, ref2s), 0, name, ntof, itof } + + +/* upb_symtab *****************************************************************/ + +struct upb_symtab { + upb_refcounted base; + + upb_strtable symtab; +}; + +struct upb_filedef { + upb_refcounted base; + + const char *name; + const char *package; + const char *phpprefix; + const char *phpnamespace; + upb_syntax_t syntax; + + upb_inttable defs; + upb_inttable deps; +}; + +extern const struct upb_refcounted_vtbl upb_filedef_vtbl; + +#endif /* UPB_STATICINIT_H_ */