package com.hubspot.jackson.datatype.protobuf; import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility; import com.fasterxml.jackson.core.Version; import com.fasterxml.jackson.databind.JsonDeserializer; import com.fasterxml.jackson.databind.Module; import com.fasterxml.jackson.databind.module.SimpleDeserializers; import com.fasterxml.jackson.databind.module.SimpleSerializers; import com.google.protobuf.BoolValue; import com.google.protobuf.BytesValue; import com.google.protobuf.DoubleValue; import com.google.protobuf.Duration; import com.google.protobuf.ExtensionRegistry; import com.google.protobuf.FieldMask; import com.google.protobuf.FloatValue; import com.google.protobuf.Int32Value; import com.google.protobuf.Int64Value; import com.google.protobuf.ListValue; import com.google.protobuf.Message; import com.google.protobuf.MessageOrBuilder; import com.google.protobuf.NullValue; import com.google.protobuf.StringValue; import com.google.protobuf.Struct; import com.google.protobuf.Timestamp; import com.google.protobuf.UInt32Value; import com.google.protobuf.UInt64Value; import com.google.protobuf.Value; import com.hubspot.jackson.datatype.protobuf.builtin.deserializers.DurationDeserializer; import com.hubspot.jackson.datatype.protobuf.builtin.deserializers.FieldMaskDeserializer; import com.hubspot.jackson.datatype.protobuf.builtin.deserializers.ListValueDeserializer; import com.hubspot.jackson.datatype.protobuf.builtin.deserializers.NullValueDeserializer; import com.hubspot.jackson.datatype.protobuf.builtin.deserializers.StructDeserializer; import com.hubspot.jackson.datatype.protobuf.builtin.deserializers.TimestampDeserializer; import com.hubspot.jackson.datatype.protobuf.builtin.deserializers.ValueDeserializer; import com.hubspot.jackson.datatype.protobuf.builtin.deserializers.WrappedPrimitiveDeserializer; import com.hubspot.jackson.datatype.protobuf.builtin.serializers.DurationSerializer; import com.hubspot.jackson.datatype.protobuf.builtin.serializers.FieldMaskSerializer; import com.hubspot.jackson.datatype.protobuf.builtin.serializers.ListValueSerializer; import com.hubspot.jackson.datatype.protobuf.builtin.serializers.MessageSerializer; import com.hubspot.jackson.datatype.protobuf.builtin.serializers.NullValueSerializer; import com.hubspot.jackson.datatype.protobuf.builtin.serializers.StructSerializer; import com.hubspot.jackson.datatype.protobuf.builtin.serializers.TimestampSerializer; import com.hubspot.jackson.datatype.protobuf.builtin.serializers.ValueSerializer; import com.hubspot.jackson.datatype.protobuf.builtin.serializers.WrappedPrimitiveSerializer; /** * Module to add support for reading and writing Protobufs * * Register with Jackson via {@link com.fasterxml.jackson.databind.ObjectMapper#registerModule} */ public class ProtobufModule extends Module { private final ProtobufJacksonConfig config; public ProtobufModule() { this(ProtobufJacksonConfig.builder().build()); } /** * @deprecated use {@link #ProtobufModule(ProtobufJacksonConfig)} instead */ @Deprecated public ProtobufModule(ExtensionRegistry extensionRegistry) { this(ProtobufJacksonConfig.builder().extensionRegistry(extensionRegistry).build()); } public ProtobufModule(ProtobufJacksonConfig config) { this.config = config; } @Override public String getModuleName() { return "ProtobufModule"; } @Override public Version version() { return Version.unknownVersion(); } @Override public void setupModule(SetupContext context) { SimpleSerializers serializers = new SimpleSerializers(); serializers.addSerializer(new MessageSerializer(config)); serializers.addSerializer(new DurationSerializer()); serializers.addSerializer(new FieldMaskSerializer()); serializers.addSerializer(new ListValueSerializer()); serializers.addSerializer(new NullValueSerializer()); serializers.addSerializer(new StructSerializer()); serializers.addSerializer(new TimestampSerializer()); serializers.addSerializer(new ValueSerializer()); serializers.addSerializer(new WrappedPrimitiveSerializer<>(DoubleValue.class)); serializers.addSerializer(new WrappedPrimitiveSerializer<>(FloatValue.class)); serializers.addSerializer(new WrappedPrimitiveSerializer<>(Int64Value.class)); serializers.addSerializer(new WrappedPrimitiveSerializer<>(UInt64Value.class)); serializers.addSerializer(new WrappedPrimitiveSerializer<>(Int32Value.class)); serializers.addSerializer(new WrappedPrimitiveSerializer<>(UInt32Value.class)); serializers.addSerializer(new WrappedPrimitiveSerializer<>(BoolValue.class)); serializers.addSerializer(new WrappedPrimitiveSerializer<>(StringValue.class)); serializers.addSerializer(new WrappedPrimitiveSerializer<>(BytesValue.class)); context.addSerializers(serializers); context.addDeserializers(new MessageDeserializerFactory(config)); SimpleDeserializers deserializers = new SimpleDeserializers(); deserializers.addDeserializer(Duration.class, new DurationDeserializer()); deserializers.addDeserializer(FieldMask.class, new FieldMaskDeserializer()); deserializers.addDeserializer(ListValue.class, new ListValueDeserializer().buildAtEnd()); deserializers.addDeserializer(NullValue.class, new NullValueDeserializer()); deserializers.addDeserializer(Struct.class, new StructDeserializer().buildAtEnd()); deserializers.addDeserializer(Timestamp.class, new TimestampDeserializer()); deserializers.addDeserializer(Value.class, new ValueDeserializer().buildAtEnd()); deserializers.addDeserializer(DoubleValue.class, wrappedPrimitiveDeserializer(DoubleValue.class)); deserializers.addDeserializer(FloatValue.class, wrappedPrimitiveDeserializer(FloatValue.class)); deserializers.addDeserializer(Int64Value.class, wrappedPrimitiveDeserializer(Int64Value.class)); deserializers.addDeserializer(UInt64Value.class, wrappedPrimitiveDeserializer(UInt64Value.class)); deserializers.addDeserializer(Int32Value.class, wrappedPrimitiveDeserializer(Int32Value.class)); deserializers.addDeserializer(UInt32Value.class, wrappedPrimitiveDeserializer(UInt32Value.class)); deserializers.addDeserializer(BoolValue.class, wrappedPrimitiveDeserializer(BoolValue.class)); deserializers.addDeserializer(StringValue.class, wrappedPrimitiveDeserializer(StringValue.class)); deserializers.addDeserializer(BytesValue.class, wrappedPrimitiveDeserializer(BytesValue.class)); context.addDeserializers(deserializers); context.setMixInAnnotations(MessageOrBuilder.class, MessageOrBuilderMixin.class); } private static <T extends Message> JsonDeserializer<T> wrappedPrimitiveDeserializer(Class<T> type) { return new WrappedPrimitiveDeserializer<>(type).buildAtEnd(); } @JsonAutoDetect(getterVisibility = Visibility.NONE, isGetterVisibility = Visibility.NONE, setterVisibility = Visibility.NONE, creatorVisibility = Visibility.NONE, fieldVisibility = Visibility.NONE) private static class MessageOrBuilderMixin { } }