go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/server/quota/internal/lua/update-accounts.gen.lua (about)

     1  -- Code generated by luapp. DO NOT EDIT.
     2  
     3  
     4  
     5  local PB = (function(...)
     6  local PB = {}
     7  
     8  local next = next
     9  local type = type
    10  
    11  PB.E = {
    12    ["go.chromium.org.luci.server.quota.quotapb.Op.Options"] = {
    13      ["NO_OPTIONS"] = 0,
    14      [0] = "NO_OPTIONS",
    15      ["IGNORE_POLICY_BOUNDS"] = 1,
    16      [1] = "IGNORE_POLICY_BOUNDS",
    17      ["DO_NOT_CAP_PROPOSED"] = 2,
    18      [2] = "DO_NOT_CAP_PROPOSED",
    19      ["WITH_POLICY_LIMIT_DELTA"] = 4,
    20      [4] = "WITH_POLICY_LIMIT_DELTA",
    21    },
    22  
    23    ["go.chromium.org.luci.server.quota.quotapb.Op.RelativeTo"] = {
    24      ["CURRENT_BALANCE"] = 0,
    25      [0] = "CURRENT_BALANCE",
    26      ["ZERO"] = 1,
    27      [1] = "ZERO",
    28      ["DEFAULT"] = 2,
    29      [2] = "DEFAULT",
    30      ["LIMIT"] = 3,
    31      [3] = "LIMIT",
    32    },
    33  
    34    ["go.chromium.org.luci.server.quota.quotapb.OpResult.AccountStatus"] = {
    35      ["ALREADY_EXISTS"] = 0,
    36      [0] = "ALREADY_EXISTS",
    37      ["CREATED"] = 1,
    38      [1] = "CREATED",
    39      ["RECREATED"] = 2,
    40      [2] = "RECREATED",
    41    },
    42  
    43    ["go.chromium.org.luci.server.quota.quotapb.OpResult.OpStatus"] = {
    44      ["SUCCESS"] = 0,
    45      [0] = "SUCCESS",
    46      ["ERR_UNKNOWN"] = 1,
    47      [1] = "ERR_UNKNOWN",
    48      ["ERR_OVERFLOW"] = 2,
    49      [2] = "ERR_OVERFLOW",
    50      ["ERR_UNDERFLOW"] = 3,
    51      [3] = "ERR_UNDERFLOW",
    52      ["ERR_UNKNOWN_POLICY"] = 4,
    53      [4] = "ERR_UNKNOWN_POLICY",
    54      ["ERR_MISSING_ACCOUNT"] = 5,
    55      [5] = "ERR_MISSING_ACCOUNT",
    56      ["ERR_POLICY_REQUIRED"] = 6,
    57      [6] = "ERR_POLICY_REQUIRED",
    58    },
    59  }
    60  
    61  PB.M = {
    62    ["go.chromium.org.luci.server.quota.quotapb.Account"] = {
    63      marshal = function(obj)
    64        local acc, val, T = {}, nil, nil, nil
    65  
    66        val = obj["balance"] -- 1: int64
    67        if val ~= 0 then
    68          local T = type(val)
    69          if T ~= "number" then
    70            error("field balance: expected number, but got "..T)
    71          end
    72          if val > 9007199254740991 then
    73            error("field balance: overflows lua max integer")
    74          end
    75          if val < -9007199254740991 then
    76            error("field balance: underflows lua min integer")
    77          end
    78          acc[1] = val
    79        end
    80  
    81        val = obj["updated_ts"] -- 2: google.protobuf.Timestamp
    82        if val ~= nil then
    83          local T = type(val)
    84          if T ~= "table" then
    85            error("field updated_ts: expected table, but got "..T)
    86          end
    87          if not val["$type"] then
    88            error("field updated_ts: missing type")
    89          end
    90          if val["$type"] ~= "google.protobuf.Timestamp" then
    91            error("field updated_ts: expected message type 'google.protobuf.Timestamp', but got "..val["$type"])
    92          end
    93          val = PB.M["google.protobuf.Timestamp"].marshal(val)
    94          acc[2] = val
    95        end
    96  
    97        val = obj["policy_change_ts"] -- 3: google.protobuf.Timestamp
    98        if val ~= nil then
    99          local T = type(val)
   100          if T ~= "table" then
   101            error("field policy_change_ts: expected table, but got "..T)
   102          end
   103          if not val["$type"] then
   104            error("field policy_change_ts: missing type")
   105          end
   106          if val["$type"] ~= "google.protobuf.Timestamp" then
   107            error("field policy_change_ts: expected message type 'google.protobuf.Timestamp', but got "..val["$type"])
   108          end
   109          val = PB.M["google.protobuf.Timestamp"].marshal(val)
   110          acc[3] = val
   111        end
   112  
   113        val = obj["policy_ref"] -- 4: go.chromium.org.luci.server.quota.quotapb.PolicyRef
   114        if val ~= nil then
   115          local T = type(val)
   116          if T ~= "table" then
   117            error("field policy_ref: expected table, but got "..T)
   118          end
   119          if not val["$type"] then
   120            error("field policy_ref: missing type")
   121          end
   122          if val["$type"] ~= "go.chromium.org.luci.server.quota.quotapb.PolicyRef" then
   123            error("field policy_ref: expected message type 'go.chromium.org.luci.server.quota.quotapb.PolicyRef', but got "..val["$type"])
   124          end
   125          val = PB.M["go.chromium.org.luci.server.quota.quotapb.PolicyRef"].marshal(val)
   126          acc[4] = val
   127        end
   128  
   129        val = obj["policy"] -- 5: go.chromium.org.luci.server.quota.quotapb.Policy
   130        if val ~= nil then
   131          local T = type(val)
   132          if T ~= "table" then
   133            error("field policy: expected table, but got "..T)
   134          end
   135          if not val["$type"] then
   136            error("field policy: missing type")
   137          end
   138          if val["$type"] ~= "go.chromium.org.luci.server.quota.quotapb.Policy" then
   139            error("field policy: expected message type 'go.chromium.org.luci.server.quota.quotapb.Policy', but got "..val["$type"])
   140          end
   141          val = PB.M["go.chromium.org.luci.server.quota.quotapb.Policy"].marshal(val)
   142          acc[5] = val
   143        end
   144  
   145        local unknown = obj["$unknown"]
   146        if unknown ~= nil then
   147          for k, v in next, unknown do acc[k] = v end
   148        end
   149        return acc
   150      end,
   151  
   152      unmarshal = function(raw)
   153        local defaults = {}
   154        local ret =  {
   155          ["$unknown"] = {},
   156          ["$type"] = "go.chromium.org.luci.server.quota.quotapb.Account",
   157          ["balance"] = 0,
   158          ["updated_ts"] = nil,
   159          ["policy_change_ts"] = nil,
   160          ["policy_ref"] = nil,
   161          ["policy"] = nil,
   162        }
   163        local dec = {
   164          [1] = function(val) -- balance: int64
   165            local T = type(val)
   166            if T ~= "number" then
   167              error("field balance: expected number, but got "..T)
   168            end
   169            ret["balance"] = val
   170          end,
   171          [2] = function(val) -- updated_ts: google.protobuf.Timestamp
   172            local T = type(val)
   173            if T ~= "table" then
   174              error("field updated_ts: expected table, but got "..T)
   175            end
   176            ret["updated_ts"] = PB.M["google.protobuf.Timestamp"].unmarshal(val)
   177          end,
   178          [3] = function(val) -- policy_change_ts: google.protobuf.Timestamp
   179            local T = type(val)
   180            if T ~= "table" then
   181              error("field policy_change_ts: expected table, but got "..T)
   182            end
   183            ret["policy_change_ts"] = PB.M["google.protobuf.Timestamp"].unmarshal(val)
   184          end,
   185          [4] = function(val) -- policy_ref: go.chromium.org.luci.server.quota.quotapb.PolicyRef
   186            local T = type(val)
   187            if T ~= "table" then
   188              error("field policy_ref: expected table, but got "..T)
   189            end
   190            ret["policy_ref"] = PB.M["go.chromium.org.luci.server.quota.quotapb.PolicyRef"].unmarshal(val)
   191          end,
   192          [5] = function(val) -- policy: go.chromium.org.luci.server.quota.quotapb.Policy
   193            local T = type(val)
   194            if T ~= "table" then
   195              error("field policy: expected table, but got "..T)
   196            end
   197            ret["policy"] = PB.M["go.chromium.org.luci.server.quota.quotapb.Policy"].unmarshal(val)
   198          end,
   199        }
   200        for k, v in next, raw do
   201          local fn = dec[k]
   202          if fn ~= nil then
   203            fn(v)
   204          else
   205            ret["$unknown"][k] = v
   206          end
   207        end
   208        return ret
   209      end,
   210      keys = {
   211        ["balance"] = true,
   212        ["updated_ts"] = true,
   213        ["policy_change_ts"] = true,
   214        ["policy_ref"] = true,
   215        ["policy"] = true,
   216      },
   217    },
   218  
   219    ["go.chromium.org.luci.server.quota.quotapb.AccountID"] = {
   220      marshal = function(obj)
   221        local acc, val, T = {}, nil, nil, nil
   222  
   223        val = obj["app_id"] -- 1: string
   224        if val ~= "" then
   225          local T = type(val)
   226          if T ~= "string" then
   227            error("field app_id: expected string, but got "..T)
   228          end
   229          acc[1] = val
   230        end
   231  
   232        val = obj["realm"] -- 2: string
   233        if val ~= "" then
   234          local T = type(val)
   235          if T ~= "string" then
   236            error("field realm: expected string, but got "..T)
   237          end
   238          acc[2] = val
   239        end
   240  
   241        val = obj["identity"] -- 3: string
   242        if val ~= "" then
   243          local T = type(val)
   244          if T ~= "string" then
   245            error("field identity: expected string, but got "..T)
   246          end
   247          acc[3] = val
   248        end
   249  
   250        val = obj["namespace"] -- 4: string
   251        if val ~= "" then
   252          local T = type(val)
   253          if T ~= "string" then
   254            error("field namespace: expected string, but got "..T)
   255          end
   256          acc[4] = val
   257        end
   258  
   259        val = obj["name"] -- 5: string
   260        if val ~= "" then
   261          local T = type(val)
   262          if T ~= "string" then
   263            error("field name: expected string, but got "..T)
   264          end
   265          acc[5] = val
   266        end
   267  
   268        val = obj["resource_type"] -- 6: string
   269        if val ~= "" then
   270          local T = type(val)
   271          if T ~= "string" then
   272            error("field resource_type: expected string, but got "..T)
   273          end
   274          acc[6] = val
   275        end
   276  
   277        local unknown = obj["$unknown"]
   278        if unknown ~= nil then
   279          for k, v in next, unknown do acc[k] = v end
   280        end
   281        return acc
   282      end,
   283  
   284      unmarshal = function(raw)
   285        local defaults = {}
   286        local ret =  {
   287          ["$unknown"] = {},
   288          ["$type"] = "go.chromium.org.luci.server.quota.quotapb.AccountID",
   289          ["app_id"] = "",
   290          ["realm"] = "",
   291          ["identity"] = "",
   292          ["namespace"] = "",
   293          ["name"] = "",
   294          ["resource_type"] = "",
   295        }
   296        local dec = {
   297          [1] = function(val) -- app_id: string
   298            local T = type(val)
   299            if T == "number" then
   300              if not PB.internUnmarshalTable then
   301                error("field app_id: failed to look up interned string: intern table not set")
   302              end
   303              local origval = val
   304              local newval = PB.internUnmarshalTable[val]
   305              if newval == nil then
   306                error("field app_id: failed to look up interned string: "..origval)
   307              end
   308              val = newval
   309              T = type(val)
   310            end
   311            if T ~= "string" then
   312              error("field app_id: expected string, but got "..T)
   313            end
   314            ret["app_id"] = val
   315          end,
   316          [2] = function(val) -- realm: string
   317            local T = type(val)
   318            if T == "number" then
   319              if not PB.internUnmarshalTable then
   320                error("field realm: failed to look up interned string: intern table not set")
   321              end
   322              local origval = val
   323              local newval = PB.internUnmarshalTable[val]
   324              if newval == nil then
   325                error("field realm: failed to look up interned string: "..origval)
   326              end
   327              val = newval
   328              T = type(val)
   329            end
   330            if T ~= "string" then
   331              error("field realm: expected string, but got "..T)
   332            end
   333            ret["realm"] = val
   334          end,
   335          [3] = function(val) -- identity: string
   336            local T = type(val)
   337            if T == "number" then
   338              if not PB.internUnmarshalTable then
   339                error("field identity: failed to look up interned string: intern table not set")
   340              end
   341              local origval = val
   342              local newval = PB.internUnmarshalTable[val]
   343              if newval == nil then
   344                error("field identity: failed to look up interned string: "..origval)
   345              end
   346              val = newval
   347              T = type(val)
   348            end
   349            if T ~= "string" then
   350              error("field identity: expected string, but got "..T)
   351            end
   352            ret["identity"] = val
   353          end,
   354          [4] = function(val) -- namespace: string
   355            local T = type(val)
   356            if T == "number" then
   357              if not PB.internUnmarshalTable then
   358                error("field namespace: failed to look up interned string: intern table not set")
   359              end
   360              local origval = val
   361              local newval = PB.internUnmarshalTable[val]
   362              if newval == nil then
   363                error("field namespace: failed to look up interned string: "..origval)
   364              end
   365              val = newval
   366              T = type(val)
   367            end
   368            if T ~= "string" then
   369              error("field namespace: expected string, but got "..T)
   370            end
   371            ret["namespace"] = val
   372          end,
   373          [5] = function(val) -- name: string
   374            local T = type(val)
   375            if T == "number" then
   376              if not PB.internUnmarshalTable then
   377                error("field name: failed to look up interned string: intern table not set")
   378              end
   379              local origval = val
   380              local newval = PB.internUnmarshalTable[val]
   381              if newval == nil then
   382                error("field name: failed to look up interned string: "..origval)
   383              end
   384              val = newval
   385              T = type(val)
   386            end
   387            if T ~= "string" then
   388              error("field name: expected string, but got "..T)
   389            end
   390            ret["name"] = val
   391          end,
   392          [6] = function(val) -- resource_type: string
   393            local T = type(val)
   394            if T == "number" then
   395              if not PB.internUnmarshalTable then
   396                error("field resource_type: failed to look up interned string: intern table not set")
   397              end
   398              local origval = val
   399              local newval = PB.internUnmarshalTable[val]
   400              if newval == nil then
   401                error("field resource_type: failed to look up interned string: "..origval)
   402              end
   403              val = newval
   404              T = type(val)
   405            end
   406            if T ~= "string" then
   407              error("field resource_type: expected string, but got "..T)
   408            end
   409            ret["resource_type"] = val
   410          end,
   411        }
   412        for k, v in next, raw do
   413          local fn = dec[k]
   414          if fn ~= nil then
   415            fn(v)
   416          else
   417            ret["$unknown"][k] = v
   418          end
   419        end
   420        return ret
   421      end,
   422      keys = {
   423        ["app_id"] = true,
   424        ["realm"] = true,
   425        ["identity"] = true,
   426        ["namespace"] = true,
   427        ["name"] = true,
   428        ["resource_type"] = true,
   429      },
   430    },
   431  
   432    ["go.chromium.org.luci.server.quota.quotapb.ApplyOpsRequest"] = {
   433      marshal = function(obj)
   434        local acc, val, T = {}, nil, nil, nil
   435  
   436        val = obj["request_id"] -- 1: string
   437        if val ~= "" then
   438          local T = type(val)
   439          if T ~= "string" then
   440            error("field request_id: expected string, but got "..T)
   441          end
   442          acc[1] = val
   443        end
   444  
   445        val = obj["request_id_ttl"] -- 2: google.protobuf.Duration
   446        if val ~= nil then
   447          local T = type(val)
   448          if T ~= "table" then
   449            error("field request_id_ttl: expected table, but got "..T)
   450          end
   451          if not val["$type"] then
   452            error("field request_id_ttl: missing type")
   453          end
   454          if val["$type"] ~= "google.protobuf.Duration" then
   455            error("field request_id_ttl: expected message type 'google.protobuf.Duration', but got "..val["$type"])
   456          end
   457          val = PB.M["google.protobuf.Duration"].marshal(val)
   458          acc[2] = val
   459        end
   460  
   461        val = obj["ops"] -- 3: repeated go.chromium.org.luci.server.quota.quotapb.Op
   462        if next(val) ~= nil then
   463          local T = type(val)
   464          if T ~= "table" then
   465            error("field ops: expected list[message], but got "..T)
   466          end
   467          local maxIdx = 0
   468          local length = 0
   469          for i, v in next, val do
   470            if type(i) ~= "number" then
   471              error("field ops: expected list[message], but got table")
   472            end
   473            local T = type(v)
   474            if T ~= "table" then
   475              error("field ops["..(i-1).."]: expected table, but got "..T)
   476            end
   477            if not v["$type"] then
   478              error("field ops["..(i-1).."]: missing type")
   479            end
   480            if v["$type"] ~= "go.chromium.org.luci.server.quota.quotapb.Op" then
   481              error("field ops["..(i-1).."]: expected message type 'go.chromium.org.luci.server.quota.quotapb.Op', but got "..v["$type"])
   482            end
   483            val[i] = PB.M["go.chromium.org.luci.server.quota.quotapb.Op"].marshal(v)
   484            if i > maxIdx then
   485              maxIdx = i
   486            end
   487            length = length + 1
   488          end
   489          if length ~= maxIdx then
   490            error("field ops: expected list[message], but got table")
   491          end
   492          acc[3] = val
   493        end
   494  
   495        local unknown = obj["$unknown"]
   496        if unknown ~= nil then
   497          for k, v in next, unknown do acc[k] = v end
   498        end
   499        return acc
   500      end,
   501  
   502      unmarshal = function(raw)
   503        local defaults = {}
   504        local ret =  {
   505          ["$unknown"] = {},
   506          ["$type"] = "go.chromium.org.luci.server.quota.quotapb.ApplyOpsRequest",
   507          ["request_id"] = "",
   508          ["request_id_ttl"] = nil,
   509          ["ops"] = {},
   510        }
   511        local dec = {
   512          [1] = function(val) -- request_id: string
   513            local T = type(val)
   514            if T == "number" then
   515              if not PB.internUnmarshalTable then
   516                error("field request_id: failed to look up interned string: intern table not set")
   517              end
   518              local origval = val
   519              local newval = PB.internUnmarshalTable[val]
   520              if newval == nil then
   521                error("field request_id: failed to look up interned string: "..origval)
   522              end
   523              val = newval
   524              T = type(val)
   525            end
   526            if T ~= "string" then
   527              error("field request_id: expected string, but got "..T)
   528            end
   529            ret["request_id"] = val
   530          end,
   531          [2] = function(val) -- request_id_ttl: google.protobuf.Duration
   532            local T = type(val)
   533            if T ~= "table" then
   534              error("field request_id_ttl: expected table, but got "..T)
   535            end
   536            ret["request_id_ttl"] = PB.M["google.protobuf.Duration"].unmarshal(val)
   537          end,
   538          [3] = function(val) -- ops: repeated go.chromium.org.luci.server.quota.quotapb.Op
   539            local T = type(val)
   540            if T ~= "table" then
   541              error("field ops: expected list[message], but got "..T)
   542            end
   543            local max = 0
   544            local count = 0
   545            for i, v in next, val do
   546              if type(i) ~= "number" then
   547                error("field ops: expected list[message], but got table")
   548              end
   549              if i > max then
   550                max = i
   551              end
   552              count = count + 1
   553              local T = type(v)
   554              if T ~= "table" then
   555                error("field ops["..(i-1).."]: expected table, but got "..T)
   556              end
   557              val[i] = PB.M["go.chromium.org.luci.server.quota.quotapb.Op"].unmarshal(v)
   558            end
   559            if max ~= count then
   560              error("field ops: expected list[message], but got table")
   561            end
   562            ret["ops"] = val
   563          end,
   564        }
   565        for k, v in next, raw do
   566          local fn = dec[k]
   567          if fn ~= nil then
   568            fn(v)
   569          else
   570            ret["$unknown"][k] = v
   571          end
   572        end
   573        return ret
   574      end,
   575      keys = {
   576        ["request_id"] = true,
   577        ["request_id_ttl"] = true,
   578        ["ops"] = true,
   579      },
   580    },
   581  
   582    ["go.chromium.org.luci.server.quota.quotapb.ApplyOpsResponse"] = {
   583      marshal = function(obj)
   584        local acc, val, T = {}, nil, nil, nil
   585  
   586        val = obj["results"] -- 1: repeated go.chromium.org.luci.server.quota.quotapb.OpResult
   587        if next(val) ~= nil then
   588          local T = type(val)
   589          if T ~= "table" then
   590            error("field results: expected list[message], but got "..T)
   591          end
   592          local maxIdx = 0
   593          local length = 0
   594          for i, v in next, val do
   595            if type(i) ~= "number" then
   596              error("field results: expected list[message], but got table")
   597            end
   598            local T = type(v)
   599            if T ~= "table" then
   600              error("field results["..(i-1).."]: expected table, but got "..T)
   601            end
   602            if not v["$type"] then
   603              error("field results["..(i-1).."]: missing type")
   604            end
   605            if v["$type"] ~= "go.chromium.org.luci.server.quota.quotapb.OpResult" then
   606              error("field results["..(i-1).."]: expected message type 'go.chromium.org.luci.server.quota.quotapb.OpResult', but got "..v["$type"])
   607            end
   608            val[i] = PB.M["go.chromium.org.luci.server.quota.quotapb.OpResult"].marshal(v)
   609            if i > maxIdx then
   610              maxIdx = i
   611            end
   612            length = length + 1
   613          end
   614          if length ~= maxIdx then
   615            error("field results: expected list[message], but got table")
   616          end
   617          acc[1] = val
   618        end
   619  
   620        val = obj["originally_set"] -- 2: google.protobuf.Timestamp
   621        if val ~= nil then
   622          local T = type(val)
   623          if T ~= "table" then
   624            error("field originally_set: expected table, but got "..T)
   625          end
   626          if not val["$type"] then
   627            error("field originally_set: missing type")
   628          end
   629          if val["$type"] ~= "google.protobuf.Timestamp" then
   630            error("field originally_set: expected message type 'google.protobuf.Timestamp', but got "..val["$type"])
   631          end
   632          val = PB.M["google.protobuf.Timestamp"].marshal(val)
   633          acc[2] = val
   634        end
   635  
   636        local unknown = obj["$unknown"]
   637        if unknown ~= nil then
   638          for k, v in next, unknown do acc[k] = v end
   639        end
   640        return acc
   641      end,
   642  
   643      unmarshal = function(raw)
   644        local defaults = {}
   645        local ret =  {
   646          ["$unknown"] = {},
   647          ["$type"] = "go.chromium.org.luci.server.quota.quotapb.ApplyOpsResponse",
   648          ["results"] = {},
   649          ["originally_set"] = nil,
   650        }
   651        local dec = {
   652          [1] = function(val) -- results: repeated go.chromium.org.luci.server.quota.quotapb.OpResult
   653            local T = type(val)
   654            if T ~= "table" then
   655              error("field results: expected list[message], but got "..T)
   656            end
   657            local max = 0
   658            local count = 0
   659            for i, v in next, val do
   660              if type(i) ~= "number" then
   661                error("field results: expected list[message], but got table")
   662              end
   663              if i > max then
   664                max = i
   665              end
   666              count = count + 1
   667              local T = type(v)
   668              if T ~= "table" then
   669                error("field results["..(i-1).."]: expected table, but got "..T)
   670              end
   671              val[i] = PB.M["go.chromium.org.luci.server.quota.quotapb.OpResult"].unmarshal(v)
   672            end
   673            if max ~= count then
   674              error("field results: expected list[message], but got table")
   675            end
   676            ret["results"] = val
   677          end,
   678          [2] = function(val) -- originally_set: google.protobuf.Timestamp
   679            local T = type(val)
   680            if T ~= "table" then
   681              error("field originally_set: expected table, but got "..T)
   682            end
   683            ret["originally_set"] = PB.M["google.protobuf.Timestamp"].unmarshal(val)
   684          end,
   685        }
   686        for k, v in next, raw do
   687          local fn = dec[k]
   688          if fn ~= nil then
   689            fn(v)
   690          else
   691            ret["$unknown"][k] = v
   692          end
   693        end
   694        return ret
   695      end,
   696      keys = {
   697        ["results"] = true,
   698        ["originally_set"] = true,
   699      },
   700    },
   701  
   702    ["go.chromium.org.luci.server.quota.quotapb.Op"] = {
   703      marshal = function(obj)
   704        local acc, val, T = {}, nil, nil, nil
   705  
   706        val = obj["account_id"] -- 1: go.chromium.org.luci.server.quota.quotapb.AccountID
   707        if val ~= nil then
   708          local T = type(val)
   709          if T ~= "table" then
   710            error("field account_id: expected table, but got "..T)
   711          end
   712          if not val["$type"] then
   713            error("field account_id: missing type")
   714          end
   715          if val["$type"] ~= "go.chromium.org.luci.server.quota.quotapb.AccountID" then
   716            error("field account_id: expected message type 'go.chromium.org.luci.server.quota.quotapb.AccountID', but got "..val["$type"])
   717          end
   718          val = PB.M["go.chromium.org.luci.server.quota.quotapb.AccountID"].marshal(val)
   719          acc[1] = val
   720        end
   721  
   722        val = obj["policy_id"] -- 2: go.chromium.org.luci.server.quota.quotapb.PolicyID
   723        if val ~= nil then
   724          local T = type(val)
   725          if T ~= "table" then
   726            error("field policy_id: expected table, but got "..T)
   727          end
   728          if not val["$type"] then
   729            error("field policy_id: missing type")
   730          end
   731          if val["$type"] ~= "go.chromium.org.luci.server.quota.quotapb.PolicyID" then
   732            error("field policy_id: expected message type 'go.chromium.org.luci.server.quota.quotapb.PolicyID', but got "..val["$type"])
   733          end
   734          val = PB.M["go.chromium.org.luci.server.quota.quotapb.PolicyID"].marshal(val)
   735          acc[2] = val
   736        end
   737  
   738        val = obj["relative_to"] -- 3: enum go.chromium.org.luci.server.quota.quotapb.Op.RelativeTo
   739        if val ~= 0 and val ~= "CURRENT_BALANCE" then
   740          local T = type(val)
   741          local origval = val
   742          if T == "string" then
   743            val = PB.E["go.chromium.org.luci.server.quota.quotapb.Op.RelativeTo"][val]
   744            if val == nil then
   745              error("field relative_to: bad string enum value "..origval)
   746            end
   747          elseif T == "number" then
   748            if PB.E["go.chromium.org.luci.server.quota.quotapb.Op.RelativeTo"][val] == nil then
   749              error("field relative_to: bad numeric enum value "..origval)
   750            end
   751          else
   752            error("field relative_to: expected number or string, but got "..T)
   753          end
   754          acc[3] = val
   755        end
   756  
   757        val = obj["delta"] -- 4: int64
   758        if val ~= 0 then
   759          local T = type(val)
   760          if T ~= "number" then
   761            error("field delta: expected number, but got "..T)
   762          end
   763          if val > 9007199254740991 then
   764            error("field delta: overflows lua max integer")
   765          end
   766          if val < -9007199254740991 then
   767            error("field delta: underflows lua min integer")
   768          end
   769          acc[4] = val
   770        end
   771  
   772        val = obj["options"] -- 5: uint32
   773        if val ~= 0 then
   774          local T = type(val)
   775          if T ~= "number" then
   776            error("field options: expected number, but got "..T)
   777          end
   778          if val < 0 then
   779            error("field options: negative")
   780          end
   781          if val > 4294967295 then
   782            error("field options: overflows max uint32")
   783          end
   784          acc[5] = val
   785        end
   786  
   787        local unknown = obj["$unknown"]
   788        if unknown ~= nil then
   789          for k, v in next, unknown do acc[k] = v end
   790        end
   791        return acc
   792      end,
   793  
   794      unmarshal = function(raw)
   795        local defaults = {}
   796        local ret =  {
   797          ["$unknown"] = {},
   798          ["$type"] = "go.chromium.org.luci.server.quota.quotapb.Op",
   799          ["account_id"] = nil,
   800          ["policy_id"] = nil,
   801          ["relative_to"] = "CURRENT_BALANCE",
   802          ["delta"] = 0,
   803          ["options"] = 0,
   804        }
   805        local dec = {
   806          [1] = function(val) -- account_id: go.chromium.org.luci.server.quota.quotapb.AccountID
   807            local T = type(val)
   808            if T ~= "table" then
   809              error("field account_id: expected table, but got "..T)
   810            end
   811            ret["account_id"] = PB.M["go.chromium.org.luci.server.quota.quotapb.AccountID"].unmarshal(val)
   812          end,
   813          [2] = function(val) -- policy_id: go.chromium.org.luci.server.quota.quotapb.PolicyID
   814            local T = type(val)
   815            if T ~= "table" then
   816              error("field policy_id: expected table, but got "..T)
   817            end
   818            ret["policy_id"] = PB.M["go.chromium.org.luci.server.quota.quotapb.PolicyID"].unmarshal(val)
   819          end,
   820          [3] = function(val) -- relative_to: enum go.chromium.org.luci.server.quota.quotapb.Op.RelativeTo
   821            local T = type(val)
   822            if T ~= "number" then
   823              error("field relative_to: expected numeric enum, but got "..T)
   824            end
   825            local origval = val
   826            local newval = PB.E["go.chromium.org.luci.server.quota.quotapb.Op.RelativeTo"][val]
   827            if newval == nil then
   828              error("field relative_to: bad enum value "..origval)
   829            end
   830            ret["relative_to"] = newval
   831          end,
   832          [4] = function(val) -- delta: int64
   833            local T = type(val)
   834            if T ~= "number" then
   835              error("field delta: expected number, but got "..T)
   836            end
   837            ret["delta"] = val
   838          end,
   839          [5] = function(val) -- options: uint32
   840            local T = type(val)
   841            if T ~= "number" then
   842              error("field options: expected number, but got "..T)
   843            end
   844            ret["options"] = val
   845          end,
   846        }
   847        for k, v in next, raw do
   848          local fn = dec[k]
   849          if fn ~= nil then
   850            fn(v)
   851          else
   852            ret["$unknown"][k] = v
   853          end
   854        end
   855        return ret
   856      end,
   857      keys = {
   858        ["account_id"] = true,
   859        ["policy_id"] = true,
   860        ["relative_to"] = true,
   861        ["delta"] = true,
   862        ["options"] = true,
   863      },
   864    },
   865  
   866    ["go.chromium.org.luci.server.quota.quotapb.OpResult"] = {
   867      marshal = function(obj)
   868        local acc, val, T = {}, nil, nil, nil
   869  
   870        val = obj["new_balance"] -- 1: int64
   871        if val ~= 0 then
   872          local T = type(val)
   873          if T ~= "number" then
   874            error("field new_balance: expected number, but got "..T)
   875          end
   876          if val > 9007199254740991 then
   877            error("field new_balance: overflows lua max integer")
   878          end
   879          if val < -9007199254740991 then
   880            error("field new_balance: underflows lua min integer")
   881          end
   882          acc[1] = val
   883        end
   884  
   885        val = obj["previous_balance"] -- 2: int64
   886        if val ~= 0 then
   887          local T = type(val)
   888          if T ~= "number" then
   889            error("field previous_balance: expected number, but got "..T)
   890          end
   891          if val > 9007199254740991 then
   892            error("field previous_balance: overflows lua max integer")
   893          end
   894          if val < -9007199254740991 then
   895            error("field previous_balance: underflows lua min integer")
   896          end
   897          acc[2] = val
   898        end
   899  
   900        val = obj["account_status"] -- 3: enum go.chromium.org.luci.server.quota.quotapb.OpResult.AccountStatus
   901        if val ~= 0 and val ~= "ALREADY_EXISTS" then
   902          local T = type(val)
   903          local origval = val
   904          if T == "string" then
   905            val = PB.E["go.chromium.org.luci.server.quota.quotapb.OpResult.AccountStatus"][val]
   906            if val == nil then
   907              error("field account_status: bad string enum value "..origval)
   908            end
   909          elseif T == "number" then
   910            if PB.E["go.chromium.org.luci.server.quota.quotapb.OpResult.AccountStatus"][val] == nil then
   911              error("field account_status: bad numeric enum value "..origval)
   912            end
   913          else
   914            error("field account_status: expected number or string, but got "..T)
   915          end
   916          acc[3] = val
   917        end
   918  
   919        val = obj["status"] -- 4: enum go.chromium.org.luci.server.quota.quotapb.OpResult.OpStatus
   920        if val ~= 0 and val ~= "SUCCESS" then
   921          local T = type(val)
   922          local origval = val
   923          if T == "string" then
   924            val = PB.E["go.chromium.org.luci.server.quota.quotapb.OpResult.OpStatus"][val]
   925            if val == nil then
   926              error("field status: bad string enum value "..origval)
   927            end
   928          elseif T == "number" then
   929            if PB.E["go.chromium.org.luci.server.quota.quotapb.OpResult.OpStatus"][val] == nil then
   930              error("field status: bad numeric enum value "..origval)
   931            end
   932          else
   933            error("field status: expected number or string, but got "..T)
   934          end
   935          acc[4] = val
   936        end
   937  
   938        val = obj["status_msg"] -- 5: string
   939        if val ~= "" then
   940          local T = type(val)
   941          if T ~= "string" then
   942            error("field status_msg: expected string, but got "..T)
   943          end
   944          acc[5] = val
   945        end
   946  
   947        val = obj["previous_balance_adjusted"] -- 6: int64
   948        if val ~= 0 then
   949          local T = type(val)
   950          if T ~= "number" then
   951            error("field previous_balance_adjusted: expected number, but got "..T)
   952          end
   953          if val > 9007199254740991 then
   954            error("field previous_balance_adjusted: overflows lua max integer")
   955          end
   956          if val < -9007199254740991 then
   957            error("field previous_balance_adjusted: underflows lua min integer")
   958          end
   959          acc[6] = val
   960        end
   961  
   962        local unknown = obj["$unknown"]
   963        if unknown ~= nil then
   964          for k, v in next, unknown do acc[k] = v end
   965        end
   966        return acc
   967      end,
   968  
   969      unmarshal = function(raw)
   970        local defaults = {}
   971        local ret =  {
   972          ["$unknown"] = {},
   973          ["$type"] = "go.chromium.org.luci.server.quota.quotapb.OpResult",
   974          ["new_balance"] = 0,
   975          ["previous_balance"] = 0,
   976          ["account_status"] = "ALREADY_EXISTS",
   977          ["status"] = "SUCCESS",
   978          ["status_msg"] = "",
   979          ["previous_balance_adjusted"] = 0,
   980        }
   981        local dec = {
   982          [1] = function(val) -- new_balance: int64
   983            local T = type(val)
   984            if T ~= "number" then
   985              error("field new_balance: expected number, but got "..T)
   986            end
   987            ret["new_balance"] = val
   988          end,
   989          [2] = function(val) -- previous_balance: int64
   990            local T = type(val)
   991            if T ~= "number" then
   992              error("field previous_balance: expected number, but got "..T)
   993            end
   994            ret["previous_balance"] = val
   995          end,
   996          [3] = function(val) -- account_status: enum go.chromium.org.luci.server.quota.quotapb.OpResult.AccountStatus
   997            local T = type(val)
   998            if T ~= "number" then
   999              error("field account_status: expected numeric enum, but got "..T)
  1000            end
  1001            local origval = val
  1002            local newval = PB.E["go.chromium.org.luci.server.quota.quotapb.OpResult.AccountStatus"][val]
  1003            if newval == nil then
  1004              error("field account_status: bad enum value "..origval)
  1005            end
  1006            ret["account_status"] = newval
  1007          end,
  1008          [4] = function(val) -- status: enum go.chromium.org.luci.server.quota.quotapb.OpResult.OpStatus
  1009            local T = type(val)
  1010            if T ~= "number" then
  1011              error("field status: expected numeric enum, but got "..T)
  1012            end
  1013            local origval = val
  1014            local newval = PB.E["go.chromium.org.luci.server.quota.quotapb.OpResult.OpStatus"][val]
  1015            if newval == nil then
  1016              error("field status: bad enum value "..origval)
  1017            end
  1018            ret["status"] = newval
  1019          end,
  1020          [5] = function(val) -- status_msg: string
  1021            local T = type(val)
  1022            if T == "number" then
  1023              if not PB.internUnmarshalTable then
  1024                error("field status_msg: failed to look up interned string: intern table not set")
  1025              end
  1026              local origval = val
  1027              local newval = PB.internUnmarshalTable[val]
  1028              if newval == nil then
  1029                error("field status_msg: failed to look up interned string: "..origval)
  1030              end
  1031              val = newval
  1032              T = type(val)
  1033            end
  1034            if T ~= "string" then
  1035              error("field status_msg: expected string, but got "..T)
  1036            end
  1037            ret["status_msg"] = val
  1038          end,
  1039          [6] = function(val) -- previous_balance_adjusted: int64
  1040            local T = type(val)
  1041            if T ~= "number" then
  1042              error("field previous_balance_adjusted: expected number, but got "..T)
  1043            end
  1044            ret["previous_balance_adjusted"] = val
  1045          end,
  1046        }
  1047        for k, v in next, raw do
  1048          local fn = dec[k]
  1049          if fn ~= nil then
  1050            fn(v)
  1051          else
  1052            ret["$unknown"][k] = v
  1053          end
  1054        end
  1055        return ret
  1056      end,
  1057      keys = {
  1058        ["new_balance"] = true,
  1059        ["previous_balance"] = true,
  1060        ["account_status"] = true,
  1061        ["status"] = true,
  1062        ["status_msg"] = true,
  1063        ["previous_balance_adjusted"] = true,
  1064      },
  1065    },
  1066  
  1067    ["go.chromium.org.luci.server.quota.quotapb.Policy"] = {
  1068      marshal = function(obj)
  1069        local acc, val, T = {}, nil, nil, nil
  1070  
  1071        val = obj["default"] -- 1: uint64
  1072        if val ~= 0 then
  1073          local T = type(val)
  1074          if T ~= "number" then
  1075            error("field default: expected number, but got "..T)
  1076          end
  1077          if val < 0 then
  1078            error("field default: negative")
  1079          end
  1080          if val > 9007199254740991 then
  1081            error("field default: overflows lua max integer")
  1082          end
  1083          acc[1] = val
  1084        end
  1085  
  1086        val = obj["limit"] -- 2: uint64
  1087        if val ~= 0 then
  1088          local T = type(val)
  1089          if T ~= "number" then
  1090            error("field limit: expected number, but got "..T)
  1091          end
  1092          if val < 0 then
  1093            error("field limit: negative")
  1094          end
  1095          if val > 9007199254740991 then
  1096            error("field limit: overflows lua max integer")
  1097          end
  1098          acc[2] = val
  1099        end
  1100  
  1101        val = obj["refill"] -- 3: go.chromium.org.luci.server.quota.quotapb.Policy.Refill
  1102        if val ~= nil then
  1103          local T = type(val)
  1104          if T ~= "table" then
  1105            error("field refill: expected table, but got "..T)
  1106          end
  1107          if not val["$type"] then
  1108            error("field refill: missing type")
  1109          end
  1110          if val["$type"] ~= "go.chromium.org.luci.server.quota.quotapb.Policy.Refill" then
  1111            error("field refill: expected message type 'go.chromium.org.luci.server.quota.quotapb.Policy.Refill', but got "..val["$type"])
  1112          end
  1113          val = PB.M["go.chromium.org.luci.server.quota.quotapb.Policy.Refill"].marshal(val)
  1114          acc[3] = val
  1115        end
  1116  
  1117        val = obj["options"] -- 4: int32
  1118        if val ~= 0 then
  1119          local T = type(val)
  1120          if T ~= "number" then
  1121            error("field options: expected number, but got "..T)
  1122          end
  1123          if val > 2147483647 then
  1124            error("field options: overflows int32")
  1125          end
  1126          if val < -2147483648 then
  1127            error("field options: underflows int32")
  1128          end
  1129          acc[4] = val
  1130        end
  1131  
  1132        val = obj["lifetime"] -- 5: google.protobuf.Duration
  1133        if val ~= nil then
  1134          local T = type(val)
  1135          if T ~= "table" then
  1136            error("field lifetime: expected table, but got "..T)
  1137          end
  1138          if not val["$type"] then
  1139            error("field lifetime: missing type")
  1140          end
  1141          if val["$type"] ~= "google.protobuf.Duration" then
  1142            error("field lifetime: expected message type 'google.protobuf.Duration', but got "..val["$type"])
  1143          end
  1144          val = PB.M["google.protobuf.Duration"].marshal(val)
  1145          acc[5] = val
  1146        end
  1147  
  1148        local unknown = obj["$unknown"]
  1149        if unknown ~= nil then
  1150          for k, v in next, unknown do acc[k] = v end
  1151        end
  1152        return acc
  1153      end,
  1154  
  1155      unmarshal = function(raw)
  1156        local defaults = {}
  1157        local ret =  {
  1158          ["$unknown"] = {},
  1159          ["$type"] = "go.chromium.org.luci.server.quota.quotapb.Policy",
  1160          ["default"] = 0,
  1161          ["limit"] = 0,
  1162          ["refill"] = nil,
  1163          ["options"] = 0,
  1164          ["lifetime"] = nil,
  1165        }
  1166        local dec = {
  1167          [1] = function(val) -- default: uint64
  1168            local T = type(val)
  1169            if T ~= "number" then
  1170              error("field default: expected number, but got "..T)
  1171            end
  1172            ret["default"] = val
  1173          end,
  1174          [2] = function(val) -- limit: uint64
  1175            local T = type(val)
  1176            if T ~= "number" then
  1177              error("field limit: expected number, but got "..T)
  1178            end
  1179            ret["limit"] = val
  1180          end,
  1181          [3] = function(val) -- refill: go.chromium.org.luci.server.quota.quotapb.Policy.Refill
  1182            local T = type(val)
  1183            if T ~= "table" then
  1184              error("field refill: expected table, but got "..T)
  1185            end
  1186            ret["refill"] = PB.M["go.chromium.org.luci.server.quota.quotapb.Policy.Refill"].unmarshal(val)
  1187          end,
  1188          [4] = function(val) -- options: int32
  1189            local T = type(val)
  1190            if T ~= "number" then
  1191              error("field options: expected number, but got "..T)
  1192            end
  1193            ret["options"] = val
  1194          end,
  1195          [5] = function(val) -- lifetime: google.protobuf.Duration
  1196            local T = type(val)
  1197            if T ~= "table" then
  1198              error("field lifetime: expected table, but got "..T)
  1199            end
  1200            ret["lifetime"] = PB.M["google.protobuf.Duration"].unmarshal(val)
  1201          end,
  1202        }
  1203        for k, v in next, raw do
  1204          local fn = dec[k]
  1205          if fn ~= nil then
  1206            fn(v)
  1207          else
  1208            ret["$unknown"][k] = v
  1209          end
  1210        end
  1211        return ret
  1212      end,
  1213      keys = {
  1214        ["default"] = true,
  1215        ["limit"] = true,
  1216        ["refill"] = true,
  1217        ["options"] = true,
  1218        ["lifetime"] = true,
  1219      },
  1220    },
  1221  
  1222    ["go.chromium.org.luci.server.quota.quotapb.Policy.Refill"] = {
  1223      marshal = function(obj)
  1224        local acc, val, T = {}, nil, nil, nil
  1225  
  1226        val = obj["units"] -- 1: int64
  1227        if val ~= 0 then
  1228          local T = type(val)
  1229          if T ~= "number" then
  1230            error("field units: expected number, but got "..T)
  1231          end
  1232          if val > 9007199254740991 then
  1233            error("field units: overflows lua max integer")
  1234          end
  1235          if val < -9007199254740991 then
  1236            error("field units: underflows lua min integer")
  1237          end
  1238          acc[1] = val
  1239        end
  1240  
  1241        val = obj["interval"] -- 2: uint32
  1242        if val ~= 0 then
  1243          local T = type(val)
  1244          if T ~= "number" then
  1245            error("field interval: expected number, but got "..T)
  1246          end
  1247          if val < 0 then
  1248            error("field interval: negative")
  1249          end
  1250          if val > 4294967295 then
  1251            error("field interval: overflows max uint32")
  1252          end
  1253          acc[2] = val
  1254        end
  1255  
  1256        val = obj["offset"] -- 3: uint32
  1257        if val ~= 0 then
  1258          local T = type(val)
  1259          if T ~= "number" then
  1260            error("field offset: expected number, but got "..T)
  1261          end
  1262          if val < 0 then
  1263            error("field offset: negative")
  1264          end
  1265          if val > 4294967295 then
  1266            error("field offset: overflows max uint32")
  1267          end
  1268          acc[3] = val
  1269        end
  1270  
  1271        local unknown = obj["$unknown"]
  1272        if unknown ~= nil then
  1273          for k, v in next, unknown do acc[k] = v end
  1274        end
  1275        return acc
  1276      end,
  1277  
  1278      unmarshal = function(raw)
  1279        local defaults = {}
  1280        local ret =  {
  1281          ["$unknown"] = {},
  1282          ["$type"] = "go.chromium.org.luci.server.quota.quotapb.Policy.Refill",
  1283          ["units"] = 0,
  1284          ["interval"] = 0,
  1285          ["offset"] = 0,
  1286        }
  1287        local dec = {
  1288          [1] = function(val) -- units: int64
  1289            local T = type(val)
  1290            if T ~= "number" then
  1291              error("field units: expected number, but got "..T)
  1292            end
  1293            ret["units"] = val
  1294          end,
  1295          [2] = function(val) -- interval: uint32
  1296            local T = type(val)
  1297            if T ~= "number" then
  1298              error("field interval: expected number, but got "..T)
  1299            end
  1300            ret["interval"] = val
  1301          end,
  1302          [3] = function(val) -- offset: uint32
  1303            local T = type(val)
  1304            if T ~= "number" then
  1305              error("field offset: expected number, but got "..T)
  1306            end
  1307            ret["offset"] = val
  1308          end,
  1309        }
  1310        for k, v in next, raw do
  1311          local fn = dec[k]
  1312          if fn ~= nil then
  1313            fn(v)
  1314          else
  1315            ret["$unknown"][k] = v
  1316          end
  1317        end
  1318        return ret
  1319      end,
  1320      keys = {
  1321        ["units"] = true,
  1322        ["interval"] = true,
  1323        ["offset"] = true,
  1324      },
  1325    },
  1326  
  1327    ["go.chromium.org.luci.server.quota.quotapb.PolicyConfigID"] = {
  1328      marshal = function(obj)
  1329        local acc, val, T = {}, nil, nil, nil
  1330  
  1331        val = obj["app_id"] -- 1: string
  1332        if val ~= "" then
  1333          local T = type(val)
  1334          if T ~= "string" then
  1335            error("field app_id: expected string, but got "..T)
  1336          end
  1337          acc[1] = val
  1338        end
  1339  
  1340        val = obj["realm"] -- 2: string
  1341        if val ~= "" then
  1342          local T = type(val)
  1343          if T ~= "string" then
  1344            error("field realm: expected string, but got "..T)
  1345          end
  1346          acc[2] = val
  1347        end
  1348  
  1349        val = obj["version_scheme"] -- 3: uint32
  1350        if val ~= 0 then
  1351          local T = type(val)
  1352          if T ~= "number" then
  1353            error("field version_scheme: expected number, but got "..T)
  1354          end
  1355          if val < 0 then
  1356            error("field version_scheme: negative")
  1357          end
  1358          if val > 4294967295 then
  1359            error("field version_scheme: overflows max uint32")
  1360          end
  1361          acc[3] = val
  1362        end
  1363  
  1364        val = obj["version"] -- 4: string
  1365        if val ~= "" then
  1366          local T = type(val)
  1367          if T ~= "string" then
  1368            error("field version: expected string, but got "..T)
  1369          end
  1370          acc[4] = val
  1371        end
  1372  
  1373        local unknown = obj["$unknown"]
  1374        if unknown ~= nil then
  1375          for k, v in next, unknown do acc[k] = v end
  1376        end
  1377        return acc
  1378      end,
  1379  
  1380      unmarshal = function(raw)
  1381        local defaults = {}
  1382        local ret =  {
  1383          ["$unknown"] = {},
  1384          ["$type"] = "go.chromium.org.luci.server.quota.quotapb.PolicyConfigID",
  1385          ["app_id"] = "",
  1386          ["realm"] = "",
  1387          ["version_scheme"] = 0,
  1388          ["version"] = "",
  1389        }
  1390        local dec = {
  1391          [1] = function(val) -- app_id: string
  1392            local T = type(val)
  1393            if T == "number" then
  1394              if not PB.internUnmarshalTable then
  1395                error("field app_id: failed to look up interned string: intern table not set")
  1396              end
  1397              local origval = val
  1398              local newval = PB.internUnmarshalTable[val]
  1399              if newval == nil then
  1400                error("field app_id: failed to look up interned string: "..origval)
  1401              end
  1402              val = newval
  1403              T = type(val)
  1404            end
  1405            if T ~= "string" then
  1406              error("field app_id: expected string, but got "..T)
  1407            end
  1408            ret["app_id"] = val
  1409          end,
  1410          [2] = function(val) -- realm: string
  1411            local T = type(val)
  1412            if T == "number" then
  1413              if not PB.internUnmarshalTable then
  1414                error("field realm: failed to look up interned string: intern table not set")
  1415              end
  1416              local origval = val
  1417              local newval = PB.internUnmarshalTable[val]
  1418              if newval == nil then
  1419                error("field realm: failed to look up interned string: "..origval)
  1420              end
  1421              val = newval
  1422              T = type(val)
  1423            end
  1424            if T ~= "string" then
  1425              error("field realm: expected string, but got "..T)
  1426            end
  1427            ret["realm"] = val
  1428          end,
  1429          [3] = function(val) -- version_scheme: uint32
  1430            local T = type(val)
  1431            if T ~= "number" then
  1432              error("field version_scheme: expected number, but got "..T)
  1433            end
  1434            ret["version_scheme"] = val
  1435          end,
  1436          [4] = function(val) -- version: string
  1437            local T = type(val)
  1438            if T == "number" then
  1439              if not PB.internUnmarshalTable then
  1440                error("field version: failed to look up interned string: intern table not set")
  1441              end
  1442              local origval = val
  1443              local newval = PB.internUnmarshalTable[val]
  1444              if newval == nil then
  1445                error("field version: failed to look up interned string: "..origval)
  1446              end
  1447              val = newval
  1448              T = type(val)
  1449            end
  1450            if T ~= "string" then
  1451              error("field version: expected string, but got "..T)
  1452            end
  1453            ret["version"] = val
  1454          end,
  1455        }
  1456        for k, v in next, raw do
  1457          local fn = dec[k]
  1458          if fn ~= nil then
  1459            fn(v)
  1460          else
  1461            ret["$unknown"][k] = v
  1462          end
  1463        end
  1464        return ret
  1465      end,
  1466      keys = {
  1467        ["app_id"] = true,
  1468        ["realm"] = true,
  1469        ["version_scheme"] = true,
  1470        ["version"] = true,
  1471      },
  1472    },
  1473  
  1474    ["go.chromium.org.luci.server.quota.quotapb.PolicyID"] = {
  1475      marshal = function(obj)
  1476        local acc, val, T = {}, nil, nil, nil
  1477  
  1478        val = obj["config"] -- 1: go.chromium.org.luci.server.quota.quotapb.PolicyConfigID
  1479        if val ~= nil then
  1480          local T = type(val)
  1481          if T ~= "table" then
  1482            error("field config: expected table, but got "..T)
  1483          end
  1484          if not val["$type"] then
  1485            error("field config: missing type")
  1486          end
  1487          if val["$type"] ~= "go.chromium.org.luci.server.quota.quotapb.PolicyConfigID" then
  1488            error("field config: expected message type 'go.chromium.org.luci.server.quota.quotapb.PolicyConfigID', but got "..val["$type"])
  1489          end
  1490          val = PB.M["go.chromium.org.luci.server.quota.quotapb.PolicyConfigID"].marshal(val)
  1491          acc[1] = val
  1492        end
  1493  
  1494        val = obj["key"] -- 2: go.chromium.org.luci.server.quota.quotapb.PolicyKey
  1495        if val ~= nil then
  1496          local T = type(val)
  1497          if T ~= "table" then
  1498            error("field key: expected table, but got "..T)
  1499          end
  1500          if not val["$type"] then
  1501            error("field key: missing type")
  1502          end
  1503          if val["$type"] ~= "go.chromium.org.luci.server.quota.quotapb.PolicyKey" then
  1504            error("field key: expected message type 'go.chromium.org.luci.server.quota.quotapb.PolicyKey', but got "..val["$type"])
  1505          end
  1506          val = PB.M["go.chromium.org.luci.server.quota.quotapb.PolicyKey"].marshal(val)
  1507          acc[2] = val
  1508        end
  1509  
  1510        local unknown = obj["$unknown"]
  1511        if unknown ~= nil then
  1512          for k, v in next, unknown do acc[k] = v end
  1513        end
  1514        return acc
  1515      end,
  1516  
  1517      unmarshal = function(raw)
  1518        local defaults = {}
  1519        local ret =  {
  1520          ["$unknown"] = {},
  1521          ["$type"] = "go.chromium.org.luci.server.quota.quotapb.PolicyID",
  1522          ["config"] = nil,
  1523          ["key"] = nil,
  1524        }
  1525        local dec = {
  1526          [1] = function(val) -- config: go.chromium.org.luci.server.quota.quotapb.PolicyConfigID
  1527            local T = type(val)
  1528            if T ~= "table" then
  1529              error("field config: expected table, but got "..T)
  1530            end
  1531            ret["config"] = PB.M["go.chromium.org.luci.server.quota.quotapb.PolicyConfigID"].unmarshal(val)
  1532          end,
  1533          [2] = function(val) -- key: go.chromium.org.luci.server.quota.quotapb.PolicyKey
  1534            local T = type(val)
  1535            if T ~= "table" then
  1536              error("field key: expected table, but got "..T)
  1537            end
  1538            ret["key"] = PB.M["go.chromium.org.luci.server.quota.quotapb.PolicyKey"].unmarshal(val)
  1539          end,
  1540        }
  1541        for k, v in next, raw do
  1542          local fn = dec[k]
  1543          if fn ~= nil then
  1544            fn(v)
  1545          else
  1546            ret["$unknown"][k] = v
  1547          end
  1548        end
  1549        return ret
  1550      end,
  1551      keys = {
  1552        ["config"] = true,
  1553        ["key"] = true,
  1554      },
  1555    },
  1556  
  1557    ["go.chromium.org.luci.server.quota.quotapb.PolicyKey"] = {
  1558      marshal = function(obj)
  1559        local acc, val, T = {}, nil, nil, nil
  1560  
  1561        val = obj["namespace"] -- 1: string
  1562        if val ~= "" then
  1563          local T = type(val)
  1564          if T ~= "string" then
  1565            error("field namespace: expected string, but got "..T)
  1566          end
  1567          acc[1] = val
  1568        end
  1569  
  1570        val = obj["name"] -- 2: string
  1571        if val ~= "" then
  1572          local T = type(val)
  1573          if T ~= "string" then
  1574            error("field name: expected string, but got "..T)
  1575          end
  1576          acc[2] = val
  1577        end
  1578  
  1579        val = obj["resource_type"] -- 3: string
  1580        if val ~= "" then
  1581          local T = type(val)
  1582          if T ~= "string" then
  1583            error("field resource_type: expected string, but got "..T)
  1584          end
  1585          acc[3] = val
  1586        end
  1587  
  1588        local unknown = obj["$unknown"]
  1589        if unknown ~= nil then
  1590          for k, v in next, unknown do acc[k] = v end
  1591        end
  1592        return acc
  1593      end,
  1594  
  1595      unmarshal = function(raw)
  1596        local defaults = {}
  1597        local ret =  {
  1598          ["$unknown"] = {},
  1599          ["$type"] = "go.chromium.org.luci.server.quota.quotapb.PolicyKey",
  1600          ["namespace"] = "",
  1601          ["name"] = "",
  1602          ["resource_type"] = "",
  1603        }
  1604        local dec = {
  1605          [1] = function(val) -- namespace: string
  1606            local T = type(val)
  1607            if T == "number" then
  1608              if not PB.internUnmarshalTable then
  1609                error("field namespace: failed to look up interned string: intern table not set")
  1610              end
  1611              local origval = val
  1612              local newval = PB.internUnmarshalTable[val]
  1613              if newval == nil then
  1614                error("field namespace: failed to look up interned string: "..origval)
  1615              end
  1616              val = newval
  1617              T = type(val)
  1618            end
  1619            if T ~= "string" then
  1620              error("field namespace: expected string, but got "..T)
  1621            end
  1622            ret["namespace"] = val
  1623          end,
  1624          [2] = function(val) -- name: string
  1625            local T = type(val)
  1626            if T == "number" then
  1627              if not PB.internUnmarshalTable then
  1628                error("field name: failed to look up interned string: intern table not set")
  1629              end
  1630              local origval = val
  1631              local newval = PB.internUnmarshalTable[val]
  1632              if newval == nil then
  1633                error("field name: failed to look up interned string: "..origval)
  1634              end
  1635              val = newval
  1636              T = type(val)
  1637            end
  1638            if T ~= "string" then
  1639              error("field name: expected string, but got "..T)
  1640            end
  1641            ret["name"] = val
  1642          end,
  1643          [3] = function(val) -- resource_type: string
  1644            local T = type(val)
  1645            if T == "number" then
  1646              if not PB.internUnmarshalTable then
  1647                error("field resource_type: failed to look up interned string: intern table not set")
  1648              end
  1649              local origval = val
  1650              local newval = PB.internUnmarshalTable[val]
  1651              if newval == nil then
  1652                error("field resource_type: failed to look up interned string: "..origval)
  1653              end
  1654              val = newval
  1655              T = type(val)
  1656            end
  1657            if T ~= "string" then
  1658              error("field resource_type: expected string, but got "..T)
  1659            end
  1660            ret["resource_type"] = val
  1661          end,
  1662        }
  1663        for k, v in next, raw do
  1664          local fn = dec[k]
  1665          if fn ~= nil then
  1666            fn(v)
  1667          else
  1668            ret["$unknown"][k] = v
  1669          end
  1670        end
  1671        return ret
  1672      end,
  1673      keys = {
  1674        ["namespace"] = true,
  1675        ["name"] = true,
  1676        ["resource_type"] = true,
  1677      },
  1678    },
  1679  
  1680    ["go.chromium.org.luci.server.quota.quotapb.PolicyRef"] = {
  1681      marshal = function(obj)
  1682        local acc, val, T = {}, nil, nil, nil
  1683  
  1684        val = obj["config"] -- 1: string
  1685        if val ~= "" then
  1686          local T = type(val)
  1687          if T ~= "string" then
  1688            error("field config: expected string, but got "..T)
  1689          end
  1690          acc[1] = val
  1691        end
  1692  
  1693        val = obj["key"] -- 2: string
  1694        if val ~= "" then
  1695          local T = type(val)
  1696          if T ~= "string" then
  1697            error("field key: expected string, but got "..T)
  1698          end
  1699          acc[2] = val
  1700        end
  1701  
  1702        local unknown = obj["$unknown"]
  1703        if unknown ~= nil then
  1704          for k, v in next, unknown do acc[k] = v end
  1705        end
  1706        return acc
  1707      end,
  1708  
  1709      unmarshal = function(raw)
  1710        local defaults = {}
  1711        local ret =  {
  1712          ["$unknown"] = {},
  1713          ["$type"] = "go.chromium.org.luci.server.quota.quotapb.PolicyRef",
  1714          ["config"] = "",
  1715          ["key"] = "",
  1716        }
  1717        local dec = {
  1718          [1] = function(val) -- config: string
  1719            local T = type(val)
  1720            if T == "number" then
  1721              if not PB.internUnmarshalTable then
  1722                error("field config: failed to look up interned string: intern table not set")
  1723              end
  1724              local origval = val
  1725              local newval = PB.internUnmarshalTable[val]
  1726              if newval == nil then
  1727                error("field config: failed to look up interned string: "..origval)
  1728              end
  1729              val = newval
  1730              T = type(val)
  1731            end
  1732            if T ~= "string" then
  1733              error("field config: expected string, but got "..T)
  1734            end
  1735            ret["config"] = val
  1736          end,
  1737          [2] = function(val) -- key: string
  1738            local T = type(val)
  1739            if T == "number" then
  1740              if not PB.internUnmarshalTable then
  1741                error("field key: failed to look up interned string: intern table not set")
  1742              end
  1743              local origval = val
  1744              local newval = PB.internUnmarshalTable[val]
  1745              if newval == nil then
  1746                error("field key: failed to look up interned string: "..origval)
  1747              end
  1748              val = newval
  1749              T = type(val)
  1750            end
  1751            if T ~= "string" then
  1752              error("field key: expected string, but got "..T)
  1753            end
  1754            ret["key"] = val
  1755          end,
  1756        }
  1757        for k, v in next, raw do
  1758          local fn = dec[k]
  1759          if fn ~= nil then
  1760            fn(v)
  1761          else
  1762            ret["$unknown"][k] = v
  1763          end
  1764        end
  1765        return ret
  1766      end,
  1767      keys = {
  1768        ["config"] = true,
  1769        ["key"] = true,
  1770      },
  1771    },
  1772  
  1773    ["go.chromium.org.luci.server.quota.quotapb.RawOp"] = {
  1774      marshal = function(obj)
  1775        local acc, val, T = {}, nil, nil, nil
  1776  
  1777        val = obj["account_ref"] -- 1: string
  1778        if val ~= "" then
  1779          local T = type(val)
  1780          if T ~= "string" then
  1781            error("field account_ref: expected string, but got "..T)
  1782          end
  1783          acc[1] = val
  1784        end
  1785  
  1786        val = obj["policy_ref"] -- 2: go.chromium.org.luci.server.quota.quotapb.PolicyRef
  1787        if val ~= nil then
  1788          local T = type(val)
  1789          if T ~= "table" then
  1790            error("field policy_ref: expected table, but got "..T)
  1791          end
  1792          if not val["$type"] then
  1793            error("field policy_ref: missing type")
  1794          end
  1795          if val["$type"] ~= "go.chromium.org.luci.server.quota.quotapb.PolicyRef" then
  1796            error("field policy_ref: expected message type 'go.chromium.org.luci.server.quota.quotapb.PolicyRef', but got "..val["$type"])
  1797          end
  1798          val = PB.M["go.chromium.org.luci.server.quota.quotapb.PolicyRef"].marshal(val)
  1799          acc[2] = val
  1800        end
  1801  
  1802        val = obj["relative_to"] -- 3: enum go.chromium.org.luci.server.quota.quotapb.Op.RelativeTo
  1803        if val ~= 0 and val ~= "CURRENT_BALANCE" then
  1804          local T = type(val)
  1805          local origval = val
  1806          if T == "string" then
  1807            val = PB.E["go.chromium.org.luci.server.quota.quotapb.Op.RelativeTo"][val]
  1808            if val == nil then
  1809              error("field relative_to: bad string enum value "..origval)
  1810            end
  1811          elseif T == "number" then
  1812            if PB.E["go.chromium.org.luci.server.quota.quotapb.Op.RelativeTo"][val] == nil then
  1813              error("field relative_to: bad numeric enum value "..origval)
  1814            end
  1815          else
  1816            error("field relative_to: expected number or string, but got "..T)
  1817          end
  1818          acc[3] = val
  1819        end
  1820  
  1821        val = obj["delta"] -- 4: int64
  1822        if val ~= 0 then
  1823          local T = type(val)
  1824          if T ~= "number" then
  1825            error("field delta: expected number, but got "..T)
  1826          end
  1827          if val > 9007199254740991 then
  1828            error("field delta: overflows lua max integer")
  1829          end
  1830          if val < -9007199254740991 then
  1831            error("field delta: underflows lua min integer")
  1832          end
  1833          acc[4] = val
  1834        end
  1835  
  1836        val = obj["options"] -- 5: uint32
  1837        if val ~= 0 then
  1838          local T = type(val)
  1839          if T ~= "number" then
  1840            error("field options: expected number, but got "..T)
  1841          end
  1842          if val < 0 then
  1843            error("field options: negative")
  1844          end
  1845          if val > 4294967295 then
  1846            error("field options: overflows max uint32")
  1847          end
  1848          acc[5] = val
  1849        end
  1850  
  1851        local unknown = obj["$unknown"]
  1852        if unknown ~= nil then
  1853          for k, v in next, unknown do acc[k] = v end
  1854        end
  1855        return acc
  1856      end,
  1857  
  1858      unmarshal = function(raw)
  1859        local defaults = {}
  1860        local ret =  {
  1861          ["$unknown"] = {},
  1862          ["$type"] = "go.chromium.org.luci.server.quota.quotapb.RawOp",
  1863          ["account_ref"] = "",
  1864          ["policy_ref"] = nil,
  1865          ["relative_to"] = "CURRENT_BALANCE",
  1866          ["delta"] = 0,
  1867          ["options"] = 0,
  1868        }
  1869        local dec = {
  1870          [1] = function(val) -- account_ref: string
  1871            local T = type(val)
  1872            if T == "number" then
  1873              if not PB.internUnmarshalTable then
  1874                error("field account_ref: failed to look up interned string: intern table not set")
  1875              end
  1876              local origval = val
  1877              local newval = PB.internUnmarshalTable[val]
  1878              if newval == nil then
  1879                error("field account_ref: failed to look up interned string: "..origval)
  1880              end
  1881              val = newval
  1882              T = type(val)
  1883            end
  1884            if T ~= "string" then
  1885              error("field account_ref: expected string, but got "..T)
  1886            end
  1887            ret["account_ref"] = val
  1888          end,
  1889          [2] = function(val) -- policy_ref: go.chromium.org.luci.server.quota.quotapb.PolicyRef
  1890            local T = type(val)
  1891            if T ~= "table" then
  1892              error("field policy_ref: expected table, but got "..T)
  1893            end
  1894            ret["policy_ref"] = PB.M["go.chromium.org.luci.server.quota.quotapb.PolicyRef"].unmarshal(val)
  1895          end,
  1896          [3] = function(val) -- relative_to: enum go.chromium.org.luci.server.quota.quotapb.Op.RelativeTo
  1897            local T = type(val)
  1898            if T ~= "number" then
  1899              error("field relative_to: expected numeric enum, but got "..T)
  1900            end
  1901            local origval = val
  1902            local newval = PB.E["go.chromium.org.luci.server.quota.quotapb.Op.RelativeTo"][val]
  1903            if newval == nil then
  1904              error("field relative_to: bad enum value "..origval)
  1905            end
  1906            ret["relative_to"] = newval
  1907          end,
  1908          [4] = function(val) -- delta: int64
  1909            local T = type(val)
  1910            if T ~= "number" then
  1911              error("field delta: expected number, but got "..T)
  1912            end
  1913            ret["delta"] = val
  1914          end,
  1915          [5] = function(val) -- options: uint32
  1916            local T = type(val)
  1917            if T ~= "number" then
  1918              error("field options: expected number, but got "..T)
  1919            end
  1920            ret["options"] = val
  1921          end,
  1922        }
  1923        for k, v in next, raw do
  1924          local fn = dec[k]
  1925          if fn ~= nil then
  1926            fn(v)
  1927          else
  1928            ret["$unknown"][k] = v
  1929          end
  1930        end
  1931        return ret
  1932      end,
  1933      keys = {
  1934        ["account_ref"] = true,
  1935        ["policy_ref"] = true,
  1936        ["relative_to"] = true,
  1937        ["delta"] = true,
  1938        ["options"] = true,
  1939      },
  1940    },
  1941  
  1942    ["go.chromium.org.luci.server.quota.quotapb.UpdateAccountsInput"] = {
  1943      marshal = function(obj)
  1944        local acc, val, T = {}, nil, nil, nil
  1945  
  1946        val = obj["request_key"] -- 1: string
  1947        if val ~= "" then
  1948          local T = type(val)
  1949          if T ~= "string" then
  1950            error("field request_key: expected string, but got "..T)
  1951          end
  1952          acc[1] = val
  1953        end
  1954  
  1955        val = obj["request_key_ttl"] -- 2: google.protobuf.Duration
  1956        if val ~= nil then
  1957          local T = type(val)
  1958          if T ~= "table" then
  1959            error("field request_key_ttl: expected table, but got "..T)
  1960          end
  1961          if not val["$type"] then
  1962            error("field request_key_ttl: missing type")
  1963          end
  1964          if val["$type"] ~= "google.protobuf.Duration" then
  1965            error("field request_key_ttl: expected message type 'google.protobuf.Duration', but got "..val["$type"])
  1966          end
  1967          val = PB.M["google.protobuf.Duration"].marshal(val)
  1968          acc[2] = val
  1969        end
  1970  
  1971        val = obj["hash_scheme"] -- 3: uint32
  1972        if val ~= 0 then
  1973          local T = type(val)
  1974          if T ~= "number" then
  1975            error("field hash_scheme: expected number, but got "..T)
  1976          end
  1977          if val < 0 then
  1978            error("field hash_scheme: negative")
  1979          end
  1980          if val > 4294967295 then
  1981            error("field hash_scheme: overflows max uint32")
  1982          end
  1983          acc[3] = val
  1984        end
  1985  
  1986        val = obj["hash"] -- 4: string
  1987        if val ~= "" then
  1988          local T = type(val)
  1989          if T ~= "string" then
  1990            error("field hash: expected string, but got "..T)
  1991          end
  1992          acc[4] = val
  1993        end
  1994  
  1995        val = obj["ops"] -- 5: repeated go.chromium.org.luci.server.quota.quotapb.RawOp
  1996        if next(val) ~= nil then
  1997          local T = type(val)
  1998          if T ~= "table" then
  1999            error("field ops: expected list[message], but got "..T)
  2000          end
  2001          local maxIdx = 0
  2002          local length = 0
  2003          for i, v in next, val do
  2004            if type(i) ~= "number" then
  2005              error("field ops: expected list[message], but got table")
  2006            end
  2007            local T = type(v)
  2008            if T ~= "table" then
  2009              error("field ops["..(i-1).."]: expected table, but got "..T)
  2010            end
  2011            if not v["$type"] then
  2012              error("field ops["..(i-1).."]: missing type")
  2013            end
  2014            if v["$type"] ~= "go.chromium.org.luci.server.quota.quotapb.RawOp" then
  2015              error("field ops["..(i-1).."]: expected message type 'go.chromium.org.luci.server.quota.quotapb.RawOp', but got "..v["$type"])
  2016            end
  2017            val[i] = PB.M["go.chromium.org.luci.server.quota.quotapb.RawOp"].marshal(v)
  2018            if i > maxIdx then
  2019              maxIdx = i
  2020            end
  2021            length = length + 1
  2022          end
  2023          if length ~= maxIdx then
  2024            error("field ops: expected list[message], but got table")
  2025          end
  2026          acc[5] = val
  2027        end
  2028  
  2029        local unknown = obj["$unknown"]
  2030        if unknown ~= nil then
  2031          for k, v in next, unknown do acc[k] = v end
  2032        end
  2033        return acc
  2034      end,
  2035  
  2036      unmarshal = function(raw)
  2037        local defaults = {}
  2038        local ret =  {
  2039          ["$unknown"] = {},
  2040          ["$type"] = "go.chromium.org.luci.server.quota.quotapb.UpdateAccountsInput",
  2041          ["request_key"] = "",
  2042          ["request_key_ttl"] = nil,
  2043          ["hash_scheme"] = 0,
  2044          ["hash"] = "",
  2045          ["ops"] = {},
  2046        }
  2047        local dec = {
  2048          [1] = function(val) -- request_key: string
  2049            local T = type(val)
  2050            if T == "number" then
  2051              if not PB.internUnmarshalTable then
  2052                error("field request_key: failed to look up interned string: intern table not set")
  2053              end
  2054              local origval = val
  2055              local newval = PB.internUnmarshalTable[val]
  2056              if newval == nil then
  2057                error("field request_key: failed to look up interned string: "..origval)
  2058              end
  2059              val = newval
  2060              T = type(val)
  2061            end
  2062            if T ~= "string" then
  2063              error("field request_key: expected string, but got "..T)
  2064            end
  2065            ret["request_key"] = val
  2066          end,
  2067          [2] = function(val) -- request_key_ttl: google.protobuf.Duration
  2068            local T = type(val)
  2069            if T ~= "table" then
  2070              error("field request_key_ttl: expected table, but got "..T)
  2071            end
  2072            ret["request_key_ttl"] = PB.M["google.protobuf.Duration"].unmarshal(val)
  2073          end,
  2074          [3] = function(val) -- hash_scheme: uint32
  2075            local T = type(val)
  2076            if T ~= "number" then
  2077              error("field hash_scheme: expected number, but got "..T)
  2078            end
  2079            ret["hash_scheme"] = val
  2080          end,
  2081          [4] = function(val) -- hash: string
  2082            local T = type(val)
  2083            if T == "number" then
  2084              if not PB.internUnmarshalTable then
  2085                error("field hash: failed to look up interned string: intern table not set")
  2086              end
  2087              local origval = val
  2088              local newval = PB.internUnmarshalTable[val]
  2089              if newval == nil then
  2090                error("field hash: failed to look up interned string: "..origval)
  2091              end
  2092              val = newval
  2093              T = type(val)
  2094            end
  2095            if T ~= "string" then
  2096              error("field hash: expected string, but got "..T)
  2097            end
  2098            ret["hash"] = val
  2099          end,
  2100          [5] = function(val) -- ops: repeated go.chromium.org.luci.server.quota.quotapb.RawOp
  2101            local T = type(val)
  2102            if T ~= "table" then
  2103              error("field ops: expected list[message], but got "..T)
  2104            end
  2105            local max = 0
  2106            local count = 0
  2107            for i, v in next, val do
  2108              if type(i) ~= "number" then
  2109                error("field ops: expected list[message], but got table")
  2110              end
  2111              if i > max then
  2112                max = i
  2113              end
  2114              count = count + 1
  2115              local T = type(v)
  2116              if T ~= "table" then
  2117                error("field ops["..(i-1).."]: expected table, but got "..T)
  2118              end
  2119              val[i] = PB.M["go.chromium.org.luci.server.quota.quotapb.RawOp"].unmarshal(v)
  2120            end
  2121            if max ~= count then
  2122              error("field ops: expected list[message], but got table")
  2123            end
  2124            ret["ops"] = val
  2125          end,
  2126        }
  2127        for k, v in next, raw do
  2128          local fn = dec[k]
  2129          if fn ~= nil then
  2130            fn(v)
  2131          else
  2132            ret["$unknown"][k] = v
  2133          end
  2134        end
  2135        return ret
  2136      end,
  2137      keys = {
  2138        ["request_key"] = true,
  2139        ["request_key_ttl"] = true,
  2140        ["hash_scheme"] = true,
  2141        ["hash"] = true,
  2142        ["ops"] = true,
  2143      },
  2144    },
  2145  
  2146    ["google.protobuf.Duration"] = {
  2147      marshal = function(obj)
  2148        local acc, val, T = {}, nil, nil, nil
  2149  
  2150        val = obj["seconds"] -- 1: int64
  2151        if val ~= 0 then
  2152          local T = type(val)
  2153          if T ~= "number" then
  2154            error("field seconds: expected number, but got "..T)
  2155          end
  2156          if val > 9007199254740991 then
  2157            error("field seconds: overflows lua max integer")
  2158          end
  2159          if val < -9007199254740991 then
  2160            error("field seconds: underflows lua min integer")
  2161          end
  2162          acc[1] = val
  2163        end
  2164  
  2165        val = obj["nanos"] -- 2: int32
  2166        if val ~= 0 then
  2167          local T = type(val)
  2168          if T ~= "number" then
  2169            error("field nanos: expected number, but got "..T)
  2170          end
  2171          if val > 2147483647 then
  2172            error("field nanos: overflows int32")
  2173          end
  2174          if val < -2147483648 then
  2175            error("field nanos: underflows int32")
  2176          end
  2177          acc[2] = val
  2178        end
  2179  
  2180        local unknown = obj["$unknown"]
  2181        if unknown ~= nil then
  2182          for k, v in next, unknown do acc[k] = v end
  2183        end
  2184        return acc
  2185      end,
  2186  
  2187      unmarshal = function(raw)
  2188        local defaults = {}
  2189        local ret =  {
  2190          ["$unknown"] = {},
  2191          ["$type"] = "google.protobuf.Duration",
  2192          ["seconds"] = 0,
  2193          ["nanos"] = 0,
  2194        }
  2195        local dec = {
  2196          [1] = function(val) -- seconds: int64
  2197            local T = type(val)
  2198            if T ~= "number" then
  2199              error("field seconds: expected number, but got "..T)
  2200            end
  2201            ret["seconds"] = val
  2202          end,
  2203          [2] = function(val) -- nanos: int32
  2204            local T = type(val)
  2205            if T ~= "number" then
  2206              error("field nanos: expected number, but got "..T)
  2207            end
  2208            ret["nanos"] = val
  2209          end,
  2210        }
  2211        for k, v in next, raw do
  2212          local fn = dec[k]
  2213          if fn ~= nil then
  2214            fn(v)
  2215          else
  2216            ret["$unknown"][k] = v
  2217          end
  2218        end
  2219        return ret
  2220      end,
  2221      keys = {
  2222        ["seconds"] = true,
  2223        ["nanos"] = true,
  2224      },
  2225    },
  2226  
  2227    ["google.protobuf.Timestamp"] = {
  2228      marshal = function(obj)
  2229        local acc, val, T = {}, nil, nil, nil
  2230  
  2231        val = obj["seconds"] -- 1: int64
  2232        if val ~= 0 then
  2233          local T = type(val)
  2234          if T ~= "number" then
  2235            error("field seconds: expected number, but got "..T)
  2236          end
  2237          if val > 9007199254740991 then
  2238            error("field seconds: overflows lua max integer")
  2239          end
  2240          if val < -9007199254740991 then
  2241            error("field seconds: underflows lua min integer")
  2242          end
  2243          acc[1] = val
  2244        end
  2245  
  2246        val = obj["nanos"] -- 2: int32
  2247        if val ~= 0 then
  2248          local T = type(val)
  2249          if T ~= "number" then
  2250            error("field nanos: expected number, but got "..T)
  2251          end
  2252          if val > 2147483647 then
  2253            error("field nanos: overflows int32")
  2254          end
  2255          if val < -2147483648 then
  2256            error("field nanos: underflows int32")
  2257          end
  2258          acc[2] = val
  2259        end
  2260  
  2261        local unknown = obj["$unknown"]
  2262        if unknown ~= nil then
  2263          for k, v in next, unknown do acc[k] = v end
  2264        end
  2265        return acc
  2266      end,
  2267  
  2268      unmarshal = function(raw)
  2269        local defaults = {}
  2270        local ret =  {
  2271          ["$unknown"] = {},
  2272          ["$type"] = "google.protobuf.Timestamp",
  2273          ["seconds"] = 0,
  2274          ["nanos"] = 0,
  2275        }
  2276        local dec = {
  2277          [1] = function(val) -- seconds: int64
  2278            local T = type(val)
  2279            if T ~= "number" then
  2280              error("field seconds: expected number, but got "..T)
  2281            end
  2282            ret["seconds"] = val
  2283          end,
  2284          [2] = function(val) -- nanos: int32
  2285            local T = type(val)
  2286            if T ~= "number" then
  2287              error("field nanos: expected number, but got "..T)
  2288            end
  2289            ret["nanos"] = val
  2290          end,
  2291        }
  2292        for k, v in next, raw do
  2293          local fn = dec[k]
  2294          if fn ~= nil then
  2295            fn(v)
  2296          else
  2297            ret["$unknown"][k] = v
  2298          end
  2299        end
  2300        return ret
  2301      end,
  2302      keys = {
  2303        ["seconds"] = true,
  2304        ["nanos"] = true,
  2305      },
  2306    },
  2307  }
  2308  
  2309  if cmsgpack == nil then
  2310    local cmsgpack = ...
  2311    assert(cmsgpack)
  2312  end
  2313  local cmsgpack_pack = cmsgpack.pack
  2314  local cmsgpack_unpack = cmsgpack.unpack
  2315  function PB.setInternTable(t)
  2316    if PB.internUnmarshalTable then
  2317      error("cannot set intern table twice")
  2318    end
  2319    if type(t) ~= "table" then
  2320      error("must call PB.setInternTable with a table (got "..type(t)..")")
  2321    end
  2322    PB.internUnmarshalTable = {}
  2323    for i, v in ipairs(t) do
  2324      PB.internUnmarshalTable[i-1] = v
  2325    end
  2326  end
  2327  function PB.marshal(obj)
  2328    local T = obj["$type"]
  2329    if T == nil then
  2330      error("obj is missing '$type' field")
  2331    end
  2332    local codec = PB.M[T]
  2333    if codec == nil then
  2334      error("unknown proto message type: "..T)
  2335    end
  2336    return cmsgpack_pack(codec.marshal(obj))
  2337  end
  2338  function PB.unmarshal(messageName, msgpackpb)
  2339    local codec = PB.M[messageName]
  2340    if codec == nil then
  2341      error("unknown proto message type: "..messageName)
  2342    end
  2343    return codec.unmarshal(cmsgpack_unpack(msgpackpb))
  2344  end
  2345  function PB.new(messageName, defaults)
  2346    local codec = PB.M[messageName]
  2347    if codec == nil then
  2348      error("unknown proto message type: "..messageName)
  2349    end
  2350    local ret = codec.unmarshal({})
  2351    if defaults ~= nil then
  2352      for k, v in next, defaults do
  2353        if k[0] ~= "$" then
  2354          if not codec.keys[k] then
  2355            error("invalid property name '"..k.."' for "..messageName)
  2356          end
  2357          ret[k] = v
  2358        end
  2359      end
  2360    end
  2361    return ret
  2362  end
  2363  return PB
  2364  end)(cmsgpack)
  2365  PB.setInternTable(KEYS)
  2366  
  2367  local Utils = (function(...)
  2368  
  2369  local PB = ...
  2370  assert(PB)
  2371  
  2372  local redis = redis
  2373  
  2374  local Utils = {}
  2375  
  2376  local nowRaw = redis.call('TIME')
  2377  Utils.NOW = PB.new('google.protobuf.Timestamp', {
  2378    seconds = tonumber(nowRaw[1]),
  2379    nanos = tonumber(nowRaw[2]) * 1000,
  2380  })
  2381  
  2382  local math_floor = math.floor
  2383  
  2384  function Utils.Millis(duration)
  2385    if duration == nil then
  2386      return nil
  2387    end
  2388    return math_floor(duration.seconds * 1000 + duration.nanos / 1000000)
  2389  end
  2390  
  2391  function Utils.WithRequestID(req, callback)
  2392    local req_id_key = req.request_key
  2393  
  2394    if req_id_key ~= "" then
  2395      local hash_scheme, hash, response = unpack(redis.call(
  2396         "HMGET", req_id_key, "hash_scheme", "hash", "response"))
  2397      if hash_scheme ~= nil then
  2398        local my_scheme = tonumber(hash_scheme)
  2399        if response then
  2400          if req.hash_scheme ~= my_scheme then
  2401            return response
  2402          elseif req.hash_scheme == my_scheme and req.hash == hash then
  2403            return response
  2404          else
  2405            return redis.error_reply('REQUEST_HASH')
  2406          end
  2407        end
  2408      end
  2409    end
  2410  
  2411    local ret, allOK = callback()
  2412  
  2413    local response = PB.marshal(ret)
  2414  
  2415    if allOK and req_id_key ~= "" then
  2416      redis.call(
  2417        "HSET", req_id_key,
  2418        "hash_scheme", tostring(req.hash_scheme),
  2419        "hash", req.hash,
  2420        "response", response
  2421      )
  2422      local ttl = Utils.Millis(req.request_key_ttl)
  2423      if ttl == nil then
  2424        ttl = 2 * 60 * 60 * 1000
  2425      end
  2426      if ttl > 0 then
  2427        redis.call("PEXPIRE", req_id_key, ttl)
  2428      end
  2429    end
  2430  
  2431    return response
  2432  end
  2433  
  2434  return Utils
  2435  end)(PB)
  2436  
  2437  local req = PB.unmarshal("go.chromium.org.luci.server.quota.quotapb.UpdateAccountsInput", ARGV[1])
  2438  
  2439  return Utils.WithRequestID(req, function()
  2440    local Policy = (function(...)
  2441  
  2442  local PB, Utils = ...
  2443  assert(PB)
  2444  assert(Utils)
  2445  
  2446  local Policy = {
  2447    CACHE = {},
  2448  }
  2449  
  2450  local PolicyPB = "go.chromium.org.luci.server.quota.quotapb.Policy"
  2451  local PolicyRefPB = "go.chromium.org.luci.server.quota.quotapb.PolicyRef"
  2452  
  2453  function Policy.get(policy_ref)
  2454    assert(policy_ref ~= nil, "Policy:get called with <nil>")
  2455  
  2456    local configkey = policy_ref.config
  2457    local policykey = policy_ref.key
  2458  
  2459    if configkey == "" and policykey == "" then
  2460      return nil
  2461    end
  2462  
  2463    local configTable = Policy.CACHE[configkey]
  2464    if not configTable then
  2465      configTable = {}
  2466      Policy.CACHE[configkey] = configTable
  2467    end
  2468  
  2469    local entry = configTable[policykey]
  2470    if not entry then
  2471      local raw = redis.call("HGET", configkey, policykey)
  2472      if not raw then
  2473        return nil -- will result in "ERR_UNKNOWN_POLICY"
  2474      end
  2475      entry = {
  2476        policy_ref = policy_ref,
  2477        pb = PB.unmarshal(PolicyPB, raw),
  2478      }
  2479      configTable[policykey] = entry
  2480    end
  2481    return entry
  2482  end
  2483  
  2484  return Policy
  2485  end)(PB, Utils)
  2486    local Account = (function(...)
  2487  
  2488  local PB, Utils, Policy = ...
  2489  assert(PB)
  2490  assert(Utils)
  2491  assert(Policy)
  2492  
  2493  local Account = {
  2494    CACHE = {},
  2495  }
  2496  
  2497  local math_floor = math.floor
  2498  local math_min = math.min
  2499  local math_max = math.max
  2500  
  2501  local NOW = Utils.NOW
  2502  local redis_call = redis.call
  2503  
  2504  local AccountPB = "go.chromium.org.luci.server.quota.quotapb.Account"
  2505  
  2506  function Account:get(key)
  2507    assert(key, "Account:get called with <nil>")
  2508    assert(key ~= "", "Account:get called with ''")
  2509    local entry = Account.CACHE[key]
  2510    if not entry then
  2511      local raw = redis_call("GET", key)
  2512      entry = {
  2513        key = key,
  2514      }
  2515      if raw then
  2516        local ok, pb = pcall(PB.unmarshal, AccountPB, raw)
  2517        if ok then
  2518          entry.pb = pb
  2519          entry.account_status = "ALREADY_EXISTS"
  2520        else
  2521          entry.account_status = "RECREATED"
  2522        end
  2523      else
  2524        entry.account_status = "CREATED"
  2525      end
  2526      if not entry.pb then
  2527        entry.pb = PB.new(AccountPB, {
  2528          updated_ts = NOW,
  2529        })
  2530      end
  2531      setmetatable(entry, self)
  2532      self.__index = self
  2533      self.CACHE[key] = entry
  2534  
  2535      if entry.account_status == "ALREADY_EXISTS" then
  2536        entry:applyRefill()
  2537        entry.pb.updated_ts = NOW
  2538      end
  2539    end
  2540    return entry
  2541  end
  2542  
  2543  local RELATIVE_TO_CURRENT_BALANCE = "CURRENT_BALANCE"
  2544  local RELATIVE_TO_DEFAULT = "DEFAULT"
  2545  local RELATIVE_TO_LIMIT = "LIMIT"
  2546  local RELATIVE_TO_ZERO = "ZERO"
  2547  
  2548  local isInfiniteRefill = function(policy)
  2549    if not policy then
  2550      return false
  2551    end
  2552  
  2553    if not policy.refill then
  2554      return false
  2555    end
  2556  
  2557    if policy.refill.interval ~= 0 then
  2558      return false
  2559    end
  2560  
  2561    if policy.refill.units <= 0 then
  2562      error("invalid zero-interval refill policy")
  2563    end
  2564  
  2565    return true
  2566  end
  2567  
  2568  local opts = PB.E["go.chromium.org.luci.server.quota.quotapb.Op.Options"]
  2569  local IGNORE_POLICY_BOUNDS = opts.IGNORE_POLICY_BOUNDS
  2570  local DO_NOT_CAP_PROPOSED = opts.DO_NOT_CAP_PROPOSED
  2571  local WITH_POLICY_LIMIT_DELTA = opts.WITH_POLICY_LIMIT_DELTA
  2572  
  2573  local computeProposed = function(op, new_account, current, policy)
  2574    local relative_to = op.relative_to
  2575    if relative_to == RELATIVE_TO_ZERO then
  2576      return op.delta
  2577    end
  2578  
  2579    if policy == nil and new_account then
  2580      return 0, "ERR_POLICY_REQUIRED"
  2581    end
  2582  
  2583    if relative_to == RELATIVE_TO_CURRENT_BALANCE then
  2584      return current + op.delta
  2585    end
  2586  
  2587    if policy == nil then
  2588      return 0, "ERR_POLICY_REQUIRED"
  2589    end
  2590  
  2591    if relative_to == RELATIVE_TO_LIMIT then
  2592      return policy.limit + op.delta
  2593    end
  2594  
  2595    if relative_to == RELATIVE_TO_DEFAULT then
  2596      return policy.default + op.delta
  2597    end
  2598  
  2599    error("invalid `relative_to` value: "..op.relative_to)
  2600  end
  2601  
  2602  function Account:applyOp(op, result)
  2603    local options = op.options
  2604    local ignore_bounds = (options/IGNORE_POLICY_BOUNDS)%2 >= 1
  2605    local no_cap = (options/DO_NOT_CAP_PROPOSED)%2 >= 1
  2606    local with_policy_limit_delta = (options/WITH_POLICY_LIMIT_DELTA)%2 >= 1
  2607  
  2608    if op.policy_ref ~= nil then
  2609      local policy_raw = Policy.get(op.policy_ref)
  2610      if not policy_raw then
  2611        result.status = "ERR_UNKNOWN_POLICY"
  2612        return
  2613      end
  2614      self:setPolicy(policy_raw, result, with_policy_limit_delta)
  2615    end
  2616    local pb = self.pb
  2617    local policy = pb.policy
  2618  
  2619    if ignore_bounds and no_cap then
  2620      error("IGNORE_POLICY_BOUNDS and DO_NOT_CAP_PROPOSED both set")
  2621    end
  2622  
  2623    local current = pb.balance
  2624  
  2625    local proposed, status = computeProposed(op, self.account_status ~= "ALREADY_EXISTS", current, policy)
  2626    if status ~= nil then
  2627      result.status = status
  2628      return
  2629    end
  2630  
  2631    local limit = nil
  2632    if policy then
  2633      limit = policy.limit
  2634    end
  2635    if not (no_cap or ignore_bounds) then
  2636      proposed = math_min(proposed, limit)
  2637    end
  2638  
  2639    if ignore_bounds then
  2640      pb.balance = proposed
  2641    elseif policy == nil then
  2642      result.status = "ERR_POLICY_REQUIRED"
  2643      return
  2644    elseif proposed >= 0 and proposed <= limit then
  2645      if isInfiniteRefill(policy) then
  2646        pb.balance = limit
  2647      else
  2648        pb.balance = proposed
  2649      end
  2650    else
  2651      if proposed < 0 and proposed < current then
  2652        result.status = "ERR_UNDERFLOW"
  2653        return
  2654      end
  2655      if proposed > limit and proposed > current then
  2656        result.status = "ERR_OVERFLOW"
  2657        return
  2658      end
  2659      pb.balance = proposed
  2660    end
  2661  
  2662    self.account_status = "ALREADY_EXISTS"
  2663  end
  2664  
  2665  function Account:applyRefill()
  2666    local policy = self.pb.policy
  2667    if policy == nil then
  2668      return
  2669    end
  2670    local limit = policy.limit
  2671  
  2672    local refill = policy.refill
  2673    if refill == nil then
  2674      return
  2675    end
  2676  
  2677    local curBalance = self.pb.balance
  2678  
  2679    if isInfiniteRefill(policy) then
  2680      self.pb.balance = math_max(curBalance, limit)
  2681      return
  2682    end
  2683  
  2684    local units = refill.units
  2685    local interval = refill.interval
  2686  
  2687    local offset = refill.offset
  2688    local updated_unix = self.pb.updated_ts.seconds - offset
  2689    local now_unix = NOW.seconds - offset
  2690  
  2691  
  2692    local first_event_unix = (updated_unix - (updated_unix % interval)) + interval
  2693    local last_event_unix = (now_unix - (now_unix % interval))
  2694  
  2695    if last_event_unix < first_event_unix then
  2696      return
  2697    end
  2698  
  2699    local num_events = ((last_event_unix - first_event_unix) / interval) + 1
  2700    assert(math_floor(num_events) == num_events)
  2701  
  2702    local delta = num_events * units
  2703    if delta > 0 and curBalance < limit then
  2704      self.pb.balance = math_min(curBalance+delta, limit)
  2705    elseif delta < 0 and curBalance > 0 then
  2706      self.pb.balance = math_max(curBalance+delta, 0)
  2707    end
  2708  end
  2709  
  2710  local policyRefEq = function(a, b)
  2711    if a == nil and b == nil then
  2712      return true
  2713    end
  2714    if a == nil and b ~= nil then
  2715      return false
  2716    end
  2717    if a ~= nil and b == nil then
  2718      return false
  2719    end
  2720    return a.config == b.config and a.key == b.key
  2721  end
  2722  
  2723  function Account:setPolicy(policy, result, with_policy_limit_delta)
  2724    if policy then
  2725      if not policyRefEq(self.pb.policy_ref, policy.policy_ref) then
  2726        if with_policy_limit_delta and self.pb.policy_ref ~= nil then
  2727          local delta = policy.pb.limit - self.pb.policy.limit
  2728          self.pb.balance = self.pb.balance + delta
  2729  
  2730          result.previous_balance_adjusted = self.pb.balance
  2731        end
  2732  
  2733        self.pb.policy = policy.pb
  2734        self.pb.policy_ref = policy.policy_ref
  2735        self.pb.policy_change_ts = NOW
  2736      end
  2737  
  2738      if self.account_status ~= "ALREADY_EXISTS" then
  2739        self.pb.balance = policy.pb.default
  2740      end
  2741  
  2742      self:applyRefill() -- in case this policy is infinite, this will set the balance to limit.
  2743    else
  2744      self.pb.policy = nil
  2745      self.pb.policy_ref = nil
  2746      self.pb.policy_change_ts = NOW
  2747    end
  2748  end
  2749  
  2750  function Account:write()
  2751    local lifetime_ms = nil
  2752    if self.pb.policy then
  2753      lifetime_ms = Utils.Millis(self.pb.policy.lifetime)
  2754    end
  2755  
  2756    local raw = PB.marshal(self.pb)
  2757    if lifetime_ms then
  2758      redis_call('SET', self.key, raw, 'PX', lifetime_ms)
  2759    else
  2760      redis_call('SET', self.key, raw)
  2761    end
  2762  end
  2763  
  2764  function Account.ApplyOps(oplist)
  2765    local ret = PB.new("go.chromium.org.luci.server.quota.quotapb.ApplyOpsResponse")
  2766    local allOK = true
  2767    for i, op in ipairs(oplist) do
  2768      local account = Account:get(op.account_ref)
  2769  
  2770      local result = PB.new("go.chromium.org.luci.server.quota.quotapb.OpResult", {
  2771        status = "SUCCESS",  -- by default; applyOp can overwrite this.
  2772        account_status = account.account_status,
  2773        previous_balance = account.pb.balance,
  2774        previous_balance_adjusted = account.pb.balance,
  2775      })
  2776      ret.results[i] = result
  2777  
  2778      local ok, err = pcall(account.applyOp, account, op, result)
  2779      if not ok then
  2780        result.status = "ERR_UNKNOWN"
  2781        result.status_msg = tostring(err)
  2782      end
  2783  
  2784      if result.status == "SUCCESS" then
  2785        result.new_balance = account.pb.balance
  2786      else
  2787        allOK = false
  2788      end
  2789    end
  2790  
  2791    if allOK then
  2792      for key, account in pairs(Account.CACHE) do
  2793        account:write()
  2794      end
  2795      ret.originally_set = NOW
  2796    end
  2797  
  2798    return ret, allOK
  2799  end
  2800  
  2801  return Account
  2802  end)(PB, Utils, Policy)
  2803    return Account.ApplyOps(req.ops)
  2804  end)