text: "use strict";
  // See: https://github.com/vaporyco/wiki/wiki/Vapory-Contract-ABI
  import { arrayify } from "@vaporsproject/bytes";
  import { defineReadOnly } from "@vaporsproject/properties";
  import { Logger } from "@vaporsproject/logger";
  import { version } from "./_version";
  const logger = new Logger(version);
  import { Reader, Writer } from "./coders/abstract-coder";
  import { AddressCoder } from "./coders/address";
  import { ArrayCoder } from "./coders/array";
  import { BooleanCoder } from "./coders/boolean";
  import { BytesCoder } from "./coders/bytes";
  import { FixedBytesCoder } from "./coders/fixed-bytes";
  import { NullCoder } from "./coders/null";
  import { NumberCoder } from "./coders/number";
  import { StringCoder } from "./coders/string";
  import { TupleCoder } from "./coders/tuple";
  import { ParamType } from "./fragments";
  const paramTypeBytes = new RegExp(/^bytes([0-9]*)$/);
  const paramTypeNumber = new RegExp(/^(u?int)([0-9]*)$/);
  export class AbiCoder {
      constructor(coerceFunc) {
          logger.checkNew(new.target, AbiCoder);
          defineReadOnly(this, "coerceFunc", coerceFunc || null);
      }
      _getCoder(param) {
          switch (param.baseType) {
              case "address":
                  return new AddressCoder(param.name);
              case "bool":
                  return new BooleanCoder(param.name);
              case "string":
                  return new StringCoder(param.name);
              case "bytes":
                  return new BytesCoder(param.name);
              case "array":
                  return new ArrayCoder(this._getCoder(param.arrayChildren), param.arrayLength, param.name);
              case "tuple":
                  return new TupleCoder((param.components || []).map((component) => {
                      return this._getCoder(component);
                  }), param.name);
              case "":
                  return new NullCoder(param.name);
          }
          // u?int[0-9]*
          let match = param.type.match(paramTypeNumber);
          if (match) {
              let size = parseInt(match[2] || "256");
              if (size === 0 || size > 256 || (size % 8) !== 0) {
                  logger.throwArgumentError("invalid " + match[1] + " bit length", "param", param);
              }
              return new NumberCoder(size / 8, (match[1] === "int"), param.name);
          }
          // bytes[0-9]+
          match = param.type.match(paramTypeBytes);
          if (match) {
              let size = parseInt(match[1]);
              if (size === 0 || size > 32) {
                  logger.throwArgumentError("invalid bytes length", "param", param);
              }
              return new FixedBytesCoder(size, param.name);
          }
          return logger.throwArgumentError("invalid type", "type", param.type);
      }
      _getWordSize() { return 32; }
      _getReader(data, allowLoose) {
          return new Reader(data, this._getWordSize(), this.coerceFunc, allowLoose);
      }
      _getWriter() {
          return new Writer(this._getWordSize());
      }
      getDefaultValue(types) {
          const coders = types.map((type) => this._getCoder(ParamType.from(type)));
          const coder = new TupleCoder(coders, "_");
          return coder.defaultValue();
      }
      encode(types, values) {
          if (types.length !== values.length) {
              logger.throwError("types/values length mismatch", Logger.errors.INVALID_ARGUMENT, {
                  count: { types: types.length, values: values.length },
                  value: { types: types, values: values }
              });
          }
          const coders = types.map((type) => this._getCoder(ParamType.from(type)));
          const coder = (new TupleCoder(coders, "_"));
          const writer = this._getWriter();
          coder.encode(writer, values);
          return writer.data;
      }
      decode(types, data, loose) {
          const coders = types.map((type) => this._getCoder(ParamType.from(type)));
          const coder = new TupleCoder(coders, "_");
          return coder.decode(this._getReader(arrayify(data), loose));
      }
  }
  export const defaultAbiCoder = new AbiCoder();
  //# sourceMappingURL=abi-coder.js.map