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);
}