json_codec library

Descriptor-driven Proto3 JSON marshaling and unmarshaling.

Converts between Dart Map<String, Object?> message representations and Proto3 JSON format, using the same field descriptor lists as the binary marshal.dart / unmarshal.dart codecs.

Field descriptor format (same as binary marshal/unmarshal):

{
  'name'     : String,       // snake_case field name
  'number'   : int,          // protobuf field number
  'type'     : String,       // protobuf type: 'TYPE_INT32', 'TYPE_STRING', etc.
  'label'    : String?,      // 'LABEL_REPEATED' for repeated fields
  'typeName' : String?,      // fully-qualified enum/message type name
  'mapEntry' : bool?,        // true if this is a map<K,V> field
  'keyType'  : String?,      // map key type
  'valueType': String?,      // map value type
  'messageDescriptor': List<Map<String, Object?>>?,  // sub-message descriptor
  'enumValues': Map<int, String>?,  // enum ordinal -> name mapping
}

Proto3 JSON rules implemented:

  • Field names: snake_case -> lowerCamelCase in output; accept both on input.
  • int64/uint64: encoded as JSON strings (too large for JS Number).
  • bytes: encoded as base64 strings.
  • float/double: NaN -> "NaN", Infinity -> "Infinity", -Infinity -> "-Infinity".
  • enum: encoded as string name (first enum value name for ordinal 0).
  • bool: true/false.
  • message: nested JSON object.
  • repeated: JSON array.
  • map: JSON object (keys always strings in JSON).
  • Default values are omitted from output.

References:

Properties

anyTypeResolver List<Map<String, Object?>>? Function(String typeName)?
The library-global Any resolver, set by the host (e.g. conformance.dart) to enable Any JSON. It is the fallback used when a JSON (de)serialization is started without a per-call resolver — preserving full backward compatibility for callers that set this once and never thread a resolver per call.
getter/setter pair

Functions

ensureDefaults(Map<String, Object?> message, List<Map<String, Object?>> descriptor) Map<String, Object?>
Returns a copy of message with missing fields filled in with proto3 default values according to descriptor.
fieldFromJson(Object? jsonValue, String type, {String? typeName, Map<int, String>? enumValues, Map<String, int>? enumNames, List<Map<String, Object?>>? messageDescriptor, Map<String, String>? features, AnyTypeResolver? resolver}) Object?
Converts a Proto3 JSON value back to its protobuf field representation.
fieldToJson(Object? value, String type, {String? typeName, Map<int, String>? enumValues, List<Map<String, Object?>>? messageDescriptor, Map<String, String>? features, AnyTypeResolver? resolver}) Object?
Converts a single protobuf field value to its Proto3 JSON representation.
isDefaultValue(Object? value, String type) bool
Returns true if value is the proto3 default for the given field type.
isWellKnownJsonType(String typeName) bool
Whether typeName is a well-known type with a dedicated proto3-JSON form. (google.protobuf.Any is excluded — it requires a type registry.)
marshalJson(Map<String, Object?> message, List<Map<String, Object?>> descriptor) String
Marshals a message to a Proto3 JSON string.
messageFromJson(Object? json, List<Map<String, Object?>> descriptor, {List<Map<String, Object?>>? anyTypeResolver(String typeName)?}) Map<String, Object?>
Converts a proto3-JSON value json (a decoded Map/List/scalar, NOT a serialized string) into a decoded message map (snake_case proto field names).
messageToJson(Map<String, Object?> message, List<Map<String, Object?>> descriptor, {List<Map<String, Object?>>? anyTypeResolver(String typeName)?}) Object?
Converts a decoded message message (snake_case proto field names) to its proto3-JSON value — a JSON-compatible Map<String, Object?> (camelCase keys, defaults omitted), NOT a serialized string.
setAnyTypeResolver(List<Map<String, Object?>>? resolver(String typeName)?) → void
Installs the library-global anyTypeResolver hook (used to resolve the type embedded in a google.protobuf.Any during JSON conversion when no per-call resolver is supplied). Kept for backward compatibility — conformance.dart sets it once at startup.
toCamelCase(String snakeCase) String
Converts a snake_case field name to lowerCamelCase.
toSnakeCase(String camelCase) String
Converts a lowerCamelCase name to snake_case.
unmarshalJson(String jsonString, List<Map<String, Object?>> descriptor) Map<String, Object?>
Unmarshals a Proto3 JSON string into a message map.
wktFromJson(String typeName, Object? json, Map<String, String>? features, [AnyTypeResolver? resolver]) Object?
Converts proto3-JSON json into a decoded WKT message map (snake_case). resolver is the per-call Any resolver (unused by the structural WKTs, threaded only for signature uniformity).
wktToJson(String typeName, Object? value, Map<String, String>? features, [AnyTypeResolver? resolver]) Object?
Converts a decoded WKT message value (snake_case proto field names) to its proto3-JSON representation. resolver is the per-call Any resolver (unused by the structural WKTs, threaded only for signature uniformity).

Typedefs

AnyTypeResolver = List<Map<String, Object?>>? Function(String typeName)
A function resolving a message type name (stripped FQN, e.g. google.protobuf.Duration) to its field descriptor list.