fieldToJson function
Converts a single protobuf field value to its Proto3 JSON representation.
Type-specific conversions:
TYPE_INT64,TYPE_UINT64,TYPE_SINT64,TYPE_SFIXED64,TYPE_FIXED64: encoded as JSON string (too large for JS number).TYPE_BYTES: encoded as base64 string.TYPE_FLOAT,TYPE_DOUBLE: NaN/Infinity/-Infinity as string literals.TYPE_ENUM: encoded as string name using theenumValuesmap. Falls back to the integer if no name mapping is available.TYPE_MESSAGE: recursively marshaled usingmessageDescriptor.- All other scalar types pass through unchanged.
enumValues is an optional Map<int, String> mapping enum ordinals to
their Proto3 names. messageDescriptor is the nested field descriptor
list for TYPE_MESSAGE fields.
Implementation
Object? fieldToJson(
Object? value,
String type, {
String? typeName,
Map<int, String>? enumValues,
List<Map<String, Object?>>? messageDescriptor,
Map<String, String>? features,
AnyTypeResolver? resolver,
}) {
if (value == null) return null;
switch (type) {
// Signed 64-bit integers: encode as a string per the Proto3 JSON spec.
case 'TYPE_INT64':
case 'TYPE_SINT64':
case 'TYPE_SFIXED64':
return value.toString();
// Unsigned 64-bit: a Dart int holding a value >= 2^63 is stored as a
// negative bit pattern, so render it as the unsigned decimal (string).
case 'TYPE_UINT64':
case 'TYPE_FIXED64':
if (value is int && value < 0) {
return (BigInt.from(value) + (BigInt.one << 64)).toString();
}
return value.toString();
// bytes: base64 encode.
case 'TYPE_BYTES':
if (value is List<int>) {
return base64.encode(value);
}
return value;
// float / double: handle special IEEE 754 values.
case 'TYPE_FLOAT':
case 'TYPE_DOUBLE':
if (value is double) {
if (value.isNaN) return 'NaN';
if (value.isInfinite) {
return value.isNegative ? '-Infinity' : 'Infinity';
}
}
return value;
// enum: encode as string name.
case 'TYPE_ENUM':
if (enumValues != null && value is int) {
return enumValues[value] ?? value;
}
return value;
// message: recursive marshal (or a well-known-type JSON mapping).
case 'TYPE_MESSAGE':
if (typeName == 'google.protobuf.Any' &&
(resolver ?? anyTypeResolver) != null) {
return _anyToJson(value, features, resolver);
}
if (typeName != null && isWellKnownJsonType(typeName)) {
return wktToJson(typeName, value, features, resolver);
}
if (messageDescriptor != null && value is Map<String, Object?>) {
return _marshalToMap(value, messageDescriptor, resolver);
}
return value;
// string: pass through, optionally verifying UTF-8 (utf8_validation=VERIFY).
case 'TYPE_STRING':
if (value is String) {
_verifyUtf8IfRequired(value, features);
}
return value;
// All other scalar types (int32, uint32, sint32, bool,
// fixed32, sfixed32) pass through directly.
default:
return value;
}
}