ObjectEncoderContext add()

in encoders/firebase-encoders-proto/src/main/java/com/google/firebase/encoders/proto/ProtobufDataEncoderContext.java [103:195]


  ObjectEncoderContext add(
      @NonNull FieldDescriptor field, @Nullable Object obj, boolean skipDefault)
      throws IOException {
    if (obj == null) {
      return this;
    }
    if (obj instanceof CharSequence) {
      CharSequence seq = (CharSequence) obj;
      if (skipDefault && seq.length() == 0) {
        return this;
      }
      int tag = getTag(field);
      int wire = 2;
      writeVarInt32((tag << 3) | wire);
      byte[] bytes = seq.toString().getBytes(UTF_8);
      writeVarInt32(bytes.length);
      output.write(bytes);
      return this;
    }
    if (obj instanceof Collection) {
      @SuppressWarnings("unchecked")
      Collection<Object> collection = (Collection<Object>) obj;
      for (Object value : collection) {
        // It's important not to skip "default" values in repeated fields as there is a difference
        // between having an empty list and a list of "default" items,
        // e.g. encoding ["", ""] should not result in an empty list when encoded.
        add(field, value, false);
      }
      return this;
    }

    if (obj instanceof Map) {
      @SuppressWarnings("unchecked")
      Map<Object, Object> map = (Map<Object, Object>) obj;
      for (Map.Entry<Object, Object> entry : map.entrySet()) {
        // It's important not to skip "default" values in map fields as there is a difference
        // between having an empty map and a map of 2 "default" items,
        // e.g. encoding {"": 0] should not result in an empty map when encoded.
        doEncode(DEFAULT_MAP_ENCODER, field, entry, false);
      }
      return this;
    }

    if (obj instanceof Double) {
      return add(field, (double) obj, skipDefault);
    }

    if (obj instanceof Float) {
      return add(field, (float) obj, skipDefault);
    }

    if (obj instanceof Number) {
      return add(field, ((Number) obj).longValue(), skipDefault);
    }

    if (obj instanceof Boolean) {
      return add(field, (boolean) obj, skipDefault);
    }

    if (obj instanceof byte[]) {
      byte[] bytes = (byte[]) obj;
      if (skipDefault && bytes.length == 0) {
        return this;
      }
      int tag = getTag(field);
      int wire = 2;
      writeVarInt32((tag << 3) | wire);
      writeVarInt32(bytes.length);
      output.write(bytes);
      return this;
    }

    @SuppressWarnings("unchecked")
    ObjectEncoder<Object> objectEncoder =
        (ObjectEncoder<Object>) objectEncoders.get(obj.getClass());

    if (objectEncoder != null) {
      return doEncode(objectEncoder, field, obj, skipDefault);
    }
    @SuppressWarnings("unchecked")
    ValueEncoder<Object> valueEncoder = (ValueEncoder<Object>) valueEncoders.get(obj.getClass());
    if (valueEncoder != null) {
      return doEncode(valueEncoder, field, obj, skipDefault);
    }

    if (obj instanceof ProtoEnum) {
      return add(field, ((ProtoEnum) obj).getNumber());
    }
    if (obj instanceof Enum) {
      return add(field, ((Enum<?>) obj).ordinal());
    }
    return doEncode(fallbackEncoder, field, obj, skipDefault);
  }