var U = Object.defineProperty;
var l = (r, e) => U(r, "name", { value: e, configurable: !0 });
import { assert as d, assertUInt32 as D, assertInt32 as V, assertFloat32 as x } from "./assert.js";
import { protoInt64 as S } from "../proto-int64.js";
import { protoBase64 as A } from "../proto-base64.js";
import { createExtensionContainer as L } from "./extensions.js";
import { hasExtension as B, getExtension as X, setExtension as M } from "../extension-accessor.js";
import { isFieldSet as G, clearField as T } from "./reflect.js";
import { wrapField as K } from "./field-wrapper.js";
import { isScalarZeroValue as R, scalarZeroValue as W } from "./scalars.js";
import { LongType as p, ScalarType as c } from "../scalar.js";
import { isMessage as Y } from "../is-message.js";
const $ = {
  ignoreUnknownFields: !1
}, F = {
  emitDefaultValues: !1,
  enumAsInteger: !1,
  useProtoFieldName: !1,
  prettySpaces: 0
};
function P(r) {
  return r ? Object.assign(Object.assign({}, $), r) : $;
}
l(P, "makeReadOptions");
function _(r) {
  return r ? Object.assign(Object.assign({}, F), r) : F;
}
l(_, "makeWriteOptions");
const w = Symbol(), k = Symbol();
function oe() {
  return {
    makeReadOptions: P,
    makeWriteOptions: _,
    readMessage(r, e, n, a) {
      if (e == null || Array.isArray(e) || typeof e != "object")
        throw new Error(`cannot decode message ${r.typeName} from JSON: ${N(e)}`);
      a = a ?? new r();
      const t = /* @__PURE__ */ new Map(), s = n.typeRegistry;
      for (const [i, o] of Object.entries(e)) {
        const u = r.fields.findJsonName(i);
        if (u) {
          if (u.oneof) {
            if (o === null && u.kind == "scalar")
              continue;
            const f = t.get(u.oneof);
            if (f !== void 0)
              throw new Error(`cannot decode message ${r.typeName} from JSON: multiple keys for oneof "${u.oneof.name}" present: "${f}", "${i}"`);
            t.set(u.oneof, i);
          }
          O(a, o, u, n, r);
        } else {
          let f = !1;
          if (s?.findExtension && i.startsWith("[") && i.endsWith("]")) {
            const m = s.findExtension(i.substring(1, i.length - 1));
            if (m && m.extendee.typeName == r.typeName) {
              f = !0;
              const [b, y] = L(m);
              O(b, o, m.field, n, m), M(a, m, y(), n);
            }
          }
          if (!f && !n.ignoreUnknownFields)
            throw new Error(`cannot decode message ${r.typeName} from JSON: key "${i}" is unknown`);
        }
      }
      return a;
    },
    writeMessage(r, e) {
      const n = r.getType(), a = {};
      let t;
      try {
        for (t of n.fields.byNumber()) {
          if (!G(t, r)) {
            if (t.req)
              throw "required field not set";
            if (!e.emitDefaultValues || !C(t))
              continue;
          }
          const i = t.oneof ? r[t.oneof.localName].value : r[t.localName], o = J(t, i, e);
          o !== void 0 && (a[e.useProtoFieldName ? t.name : t.jsonName] = o);
        }
        const s = e.typeRegistry;
        if (s?.findExtensionFor)
          for (const i of n.runtime.bin.listUnknownFields(r)) {
            const o = s.findExtensionFor(n.typeName, i.no);
            if (o && B(r, o)) {
              const u = X(r, o, e), f = J(o.field, u, e);
              f !== void 0 && (a[o.field.jsonName] = f);
            }
          }
      } catch (s) {
        const i = t ? `cannot encode field ${n.typeName}.${t.name} to JSON` : `cannot encode message ${n.typeName} to JSON`, o = s instanceof Error ? s.message : String(s);
        throw new Error(i + (o.length > 0 ? `: ${o}` : ""));
      }
      return a;
    },
    readScalar(r, e, n) {
      return g(r, e, n ?? p.BIGINT, !0);
    },
    writeScalar(r, e, n) {
      if (e !== void 0 && (n || R(r, e)))
        return I(r, e);
    },
    debug: N
  };
}
l(oe, "makeJsonFormat");
function N(r) {
  if (r === null)
    return "null";
  switch (typeof r) {
    case "object":
      return Array.isArray(r) ? "array" : "object";
    case "string":
      return r.length > 100 ? "string" : `"${r.split('"').join('\\"')}"`;
    default:
      return String(r);
  }
}
l(N, "debugJsonValue");
function O(r, e, n, a, t) {
  let s = n.localName;
  if (n.repeated) {
    if (d(n.kind != "map"), e === null)
      return;
    if (!Array.isArray(e))
      throw new Error(`cannot decode field ${t.typeName}.${n.name} from JSON: ${N(e)}`);
    const i = r[s];
    for (const o of e) {
      if (o === null)
        throw new Error(`cannot decode field ${t.typeName}.${n.name} from JSON: ${N(o)}`);
      switch (n.kind) {
        case "message":
          i.push(n.T.fromJson(o, a));
          break;
        case "enum":
          const u = h(n.T, o, a.ignoreUnknownFields, !0);
          u !== k && i.push(u);
          break;
        case "scalar":
          try {
            i.push(g(n.T, o, n.L, !0));
          } catch (f) {
            let m = `cannot decode field ${t.typeName}.${n.name} from JSON: ${N(o)}`;
            throw f instanceof Error && f.message.length > 0 && (m += `: ${f.message}`), new Error(m);
          }
          break;
      }
    }
  } else if (n.kind == "map") {
    if (e === null)
      return;
    if (typeof e != "object" || Array.isArray(e))
      throw new Error(`cannot decode field ${t.typeName}.${n.name} from JSON: ${N(e)}`);
    const i = r[s];
    for (const [o, u] of Object.entries(e)) {
      if (u === null)
        throw new Error(`cannot decode field ${t.typeName}.${n.name} from JSON: map value null`);
      let f;
      try {
        f = q(n.K, o);
      } catch (m) {
        let b = `cannot decode map key for field ${t.typeName}.${n.name} from JSON: ${N(e)}`;
        throw m instanceof Error && m.message.length > 0 && (b += `: ${m.message}`), new Error(b);
      }
      switch (n.V.kind) {
        case "message":
          i[f] = n.V.T.fromJson(u, a);
          break;
        case "enum":
          const m = h(n.V.T, u, a.ignoreUnknownFields, !0);
          m !== k && (i[f] = m);
          break;
        case "scalar":
          try {
            i[f] = g(n.V.T, u, p.BIGINT, !0);
          } catch (b) {
            let y = `cannot decode map value for field ${t.typeName}.${n.name} from JSON: ${N(e)}`;
            throw b instanceof Error && b.message.length > 0 && (y += `: ${b.message}`), new Error(y);
          }
          break;
      }
    }
  } else
    switch (n.oneof && (r = r[n.oneof.localName] = { case: s }, s = "value"), n.kind) {
      case "message":
        const i = n.T;
        if (e === null && i.typeName != "google.protobuf.Value")
          return;
        let o = r[s];
        Y(o) ? o.fromJson(e, a) : (r[s] = o = i.fromJson(e, a), i.fieldWrapper && !n.oneof && (r[s] = i.fieldWrapper.unwrapField(o)));
        break;
      case "enum":
        const u = h(n.T, e, a.ignoreUnknownFields, !1);
        switch (u) {
          case w:
            T(n, r);
            break;
          case k:
            break;
          default:
            r[s] = u;
            break;
        }
        break;
      case "scalar":
        try {
          const f = g(n.T, e, n.L, !1);
          switch (f) {
            case w:
              T(n, r);
              break;
            default:
              r[s] = f;
              break;
          }
        } catch (f) {
          let m = `cannot decode field ${t.typeName}.${n.name} from JSON: ${N(e)}`;
          throw f instanceof Error && f.message.length > 0 && (m += `: ${f.message}`), new Error(m);
        }
        break;
    }
}
l(O, "readField");
function q(r, e) {
  if (r === c.BOOL)
    switch (e) {
      case "true":
        e = !0;
        break;
      case "false":
        e = !1;
        break;
    }
  return g(r, e, p.BIGINT, !0).toString();
}
l(q, "readMapKey");
function g(r, e, n, a) {
  if (e === null)
    return a ? W(r, n) : w;
  switch (r) {
    case c.DOUBLE:
    case c.FLOAT:
      if (e === "NaN")
        return Number.NaN;
      if (e === "Infinity")
        return Number.POSITIVE_INFINITY;
      if (e === "-Infinity")
        return Number.NEGATIVE_INFINITY;
      if (e === "" || typeof e == "string" && e.trim().length !== e.length || typeof e != "string" && typeof e != "number")
        break;
      const t = Number(e);
      if (Number.isNaN(t) || !Number.isFinite(t))
        break;
      return r == c.FLOAT && x(t), t;
    case c.INT32:
    case c.FIXED32:
    case c.SFIXED32:
    case c.SINT32:
    case c.UINT32:
      let s;
      if (typeof e == "number" ? s = e : typeof e == "string" && e.length > 0 && e.trim().length === e.length && (s = Number(e)), s === void 0)
        break;
      return r == c.UINT32 || r == c.FIXED32 ? D(s) : V(s), s;
    case c.INT64:
    case c.SFIXED64:
    case c.SINT64:
      if (typeof e != "number" && typeof e != "string")
        break;
      const i = S.parse(e);
      return n ? i.toString() : i;
    case c.FIXED64:
    case c.UINT64:
      if (typeof e != "number" && typeof e != "string")
        break;
      const o = S.uParse(e);
      return n ? o.toString() : o;
    case c.BOOL:
      if (typeof e != "boolean")
        break;
      return e;
    case c.STRING:
      if (typeof e != "string")
        break;
      try {
        encodeURIComponent(e);
      } catch {
        throw new Error("invalid UTF8");
      }
      return e;
    case c.BYTES:
      if (e === "")
        return new Uint8Array(0);
      if (typeof e != "string")
        break;
      return A.dec(e);
  }
  throw new Error();
}
l(g, "readScalar");
function h(r, e, n, a) {
  if (e === null)
    return r.typeName == "google.protobuf.NullValue" ? 0 : a ? r.values[0].no : w;
  switch (typeof e) {
    case "number":
      if (Number.isInteger(e))
        return e;
      break;
    case "string":
      const t = r.findName(e);
      if (t !== void 0)
        return t.no;
      if (n)
        return k;
      break;
  }
  throw new Error(`cannot decode enum ${r.typeName} from JSON: ${N(e)}`);
}
l(h, "readEnum");
function C(r) {
  return r.repeated || r.kind == "map" ? !0 : !(r.oneof || r.kind == "message" || r.opt || r.req);
}
l(C, "canEmitFieldDefaultValue");
function J(r, e, n) {
  if (r.kind == "map") {
    d(typeof e == "object" && e != null);
    const a = {}, t = Object.entries(e);
    switch (r.V.kind) {
      case "scalar":
        for (const [i, o] of t)
          a[i.toString()] = I(r.V.T, o);
        break;
      case "message":
        for (const [i, o] of t)
          a[i.toString()] = o.toJson(n);
        break;
      case "enum":
        const s = r.V.T;
        for (const [i, o] of t)
          a[i.toString()] = E(s, o, n.enumAsInteger);
        break;
    }
    return n.emitDefaultValues || t.length > 0 ? a : void 0;
  }
  if (r.repeated) {
    d(Array.isArray(e));
    const a = [];
    switch (r.kind) {
      case "scalar":
        for (let t = 0; t < e.length; t++)
          a.push(I(r.T, e[t]));
        break;
      case "enum":
        for (let t = 0; t < e.length; t++)
          a.push(E(r.T, e[t], n.enumAsInteger));
        break;
      case "message":
        for (let t = 0; t < e.length; t++)
          a.push(e[t].toJson(n));
        break;
    }
    return n.emitDefaultValues || a.length > 0 ? a : void 0;
  }
  switch (r.kind) {
    case "scalar":
      return I(r.T, e);
    case "enum":
      return E(r.T, e, n.enumAsInteger);
    case "message":
      return K(r.T, e).toJson(n);
  }
}
l(J, "writeField");
function E(r, e, n) {
  var a;
  if (d(typeof e == "number"), r.typeName == "google.protobuf.NullValue")
    return null;
  if (n)
    return e;
  const t = r.findNumber(e);
  return (a = t?.name) !== null && a !== void 0 ? a : e;
}
l(E, "writeEnum");
function I(r, e) {
  switch (r) {
    case c.INT32:
    case c.SFIXED32:
    case c.SINT32:
    case c.FIXED32:
    case c.UINT32:
      return d(typeof e == "number"), e;
    case c.FLOAT:
    case c.DOUBLE:
      return d(typeof e == "number"), Number.isNaN(e) ? "NaN" : e === Number.POSITIVE_INFINITY ? "Infinity" : e === Number.NEGATIVE_INFINITY ? "-Infinity" : e;
    case c.STRING:
      return d(typeof e == "string"), e;
    case c.BOOL:
      return d(typeof e == "boolean"), e;
    case c.UINT64:
    case c.FIXED64:
    case c.INT64:
    case c.SFIXED64:
    case c.SINT64:
      return d(typeof e == "bigint" || typeof e == "string" || typeof e == "number"), e.toString();
    case c.BYTES:
      return d(e instanceof Uint8Array), A.enc(e);
  }
}
l(I, "writeScalar");
export {
  oe as makeJsonFormat
};
