From 08a2aa088aab2a01ba0fcafe19ec014851af7f7e Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Tue, 2 Apr 2024 20:25:35 +0200 Subject: [PATCH 1/4] Rename custom Amino JSON encoder to inline_json and increase test coverage --- .../05-protobuf-annotations.md | 19 +++++-- x/tx/signing/aminojson/encoder.go | 9 +++- x/tx/signing/aminojson/encoder_test.go | 49 +++++++++++++++++-- x/tx/signing/aminojson/json_marshal.go | 4 +- 4 files changed, 70 insertions(+), 11 deletions(-) diff --git a/docs/build/building-modules/05-protobuf-annotations.md b/docs/build/building-modules/05-protobuf-annotations.md index 5eaee51b8139..fe212f726b0e 100644 --- a/docs/build/building-modules/05-protobuf-annotations.md +++ b/docs/build/building-modules/05-protobuf-annotations.md @@ -126,8 +126,21 @@ Encoding instructs the amino json marshaler how to encode certain fields that ma https://github.com/cosmos/cosmos-sdk/blob/e8f28bf5db18b8d6b7e0d94b542ce4cf48fed9d6/proto/cosmos/bank/v1beta1/genesis.proto#L23 ``` -Another example is how `bytes` is encoded when using the amino json encoding format. The `bytes_as_string` option tells the json marshaler [how to encode bytes as string](https://github.com/pinosu/cosmos-sdk/blob/9879ece09c58068402782fa2096199dc89a23d13/x/tx/signing/aminojson/json_marshal.go#L75). +Another example is a protobuf `bytes` that contains a valid JSON document. +The `inline_json` option tells the json marshaler to embed the JSON bytes into the wrapping document without escaping. ```proto -(amino.encoding) = "bytes_as_string", -``` \ No newline at end of file +(amino.encoding) = "inline_json", +``` + +E.g. the bytes containing `{"foo":123}` in the `envelope` field would lead to the following JSON: + +```json +{ + "envelope": { + "foo": 123 + } +} +``` + +If the bytes are not valid JSON, this leads to JSON broken documents. Thus a JSON validity check needs to be in place at some point of the process. diff --git a/x/tx/signing/aminojson/encoder.go b/x/tx/signing/aminojson/encoder.go index 5b8a91f449d7..fdd1f2310f34 100644 --- a/x/tx/signing/aminojson/encoder.go +++ b/x/tx/signing/aminojson/encoder.go @@ -81,11 +81,16 @@ func nullSliceAsEmptyEncoder(enc *Encoder, v protoreflect.Value, w io.Writer) er } } -// cosmosBytesAsString replicates the behavior at: +// cosmosInlineJSON takes bytes and inlines them into a JSON document. +// This assumes the bytes contain valid JSON since otherwise the resulting document is invalid. +// +// This replicates the behavior of JSON messages embedded in protobuf bytes +// required for CosmWasm, e.g.: // https://github.com/CosmWasm/wasmd/blob/08567ff20e372e4f4204a91ca64a371538742bed/x/wasm/types/tx.go#L20-L22 -func cosmosBytesAsString(_ *Encoder, v protoreflect.Value, w io.Writer) error { +func cosmosInlineJSON(_ *Encoder, v protoreflect.Value, w io.Writer) error { switch bz := v.Interface().(type) { case []byte: + // Caution, this does not include a validity check as json.RawMessage can be anything 🤷‍♂️ blob, err := json.RawMessage(bz).MarshalJSON() if err != nil { return err diff --git a/x/tx/signing/aminojson/encoder_test.go b/x/tx/signing/aminojson/encoder_test.go index a843238614bb..3bfa301c0723 100644 --- a/x/tx/signing/aminojson/encoder_test.go +++ b/x/tx/signing/aminojson/encoder_test.go @@ -9,18 +9,59 @@ import ( "gotest.tools/v3/assert" ) -func TestCosmosBytesAsString(t *testing.T) { +func TestCosmosInlineJSON(t *testing.T) { cases := map[string]struct { value protoreflect.Value wantErr bool wantOutput string }{ - "valid bytes - json": { + "supported type - valid JSON object": { value: protoreflect.ValueOfBytes([]byte(`{"test":"value"}`)), wantErr: false, wantOutput: `{"test":"value"}`, }, - "valid bytes - string": { + "supported type - valid JSON array": { + // spaces are normalized away + value: protoreflect.ValueOfBytes([]byte(`[1,2,3]`)), + wantErr: false, + wantOutput: `[1,2,3]`, + }, + "supported type - valid JSON is not normalized": { + value: protoreflect.ValueOfBytes([]byte(`[1, 2, 3]`)), + wantErr: false, + wantOutput: `[1, 2, 3]`, + }, + "supported type - valid JSON array (empty)": { + value: protoreflect.ValueOfBytes([]byte(`[]`)), + wantErr: false, + wantOutput: `[]`, + }, + "supported type - valid JSON number": { + value: protoreflect.ValueOfBytes([]byte(`43.72`)), + wantErr: false, + wantOutput: `43.72`, + }, + "supported type - valid JSON boolean": { + value: protoreflect.ValueOfBytes([]byte(`true`)), + wantErr: false, + wantOutput: `true`, + }, + "supported type - valid JSON null": { + value: protoreflect.ValueOfBytes([]byte(`null`)), + wantErr: false, + wantOutput: `null`, + }, + "supported type - valid JSON string": { + value: protoreflect.ValueOfBytes([]byte(`"hey yo"`)), + wantErr: false, + wantOutput: `"hey yo"`, + }, + // This test case is a bit tricky. Conceptually it makes no sense for this + // to pass. The question is just where the JSON validity check is done. + // In wasmd we have it in the message field validation. But it might make + // sense to move it here instead. + // For now it's better to consider this case undefined behaviour. + "supported type - invalid JSON": { value: protoreflect.ValueOfBytes([]byte(`foo`)), wantErr: false, wantOutput: `foo`, @@ -38,7 +79,7 @@ func TestCosmosBytesAsString(t *testing.T) { for name, tc := range cases { t.Run(name, func(t *testing.T) { var buf bytes.Buffer - err := cosmosBytesAsString(nil, tc.value, &buf) + err := cosmosInlineJSON(nil, tc.value, &buf) if tc.wantErr { require.Error(t, err) diff --git a/x/tx/signing/aminojson/json_marshal.go b/x/tx/signing/aminojson/json_marshal.go index cdbb9aa2ac21..f276cb39d23e 100644 --- a/x/tx/signing/aminojson/json_marshal.go +++ b/x/tx/signing/aminojson/json_marshal.go @@ -72,8 +72,8 @@ func NewEncoder(options EncoderOptions) Encoder { "threshold_string": thresholdStringEncoder, }, aminoFieldEncoders: map[string]FieldEncoder{ - "legacy_coins": nullSliceAsEmptyEncoder, - "bytes_as_string": cosmosBytesAsString, + "legacy_coins": nullSliceAsEmptyEncoder, + "inline_json": cosmosInlineJSON, }, protoTypeEncoders: map[string]MessageEncoder{ "google.protobuf.Timestamp": marshalTimestamp, From 5bea2095f229b02dd4ed528eab6e800539ac8120 Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Tue, 2 Apr 2024 20:31:52 +0200 Subject: [PATCH 2/4] Combine CHANGELOG entries of #19786/#19919 --- x/tx/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/tx/CHANGELOG.md b/x/tx/CHANGELOG.md index 040681ddb96c..df11b0d2fb98 100644 --- a/x/tx/CHANGELOG.md +++ b/x/tx/CHANGELOG.md @@ -33,7 +33,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### Features -* [#19786](https://github.com/cosmos/cosmos-sdk/pull/19786) Add bytes as string option to encoder. +* [#19786](https://github.com/cosmos/cosmos-sdk/pull/19786)/[#19919](https://github.com/cosmos/cosmos-sdk/pull/19919) Add "inline_json" option to Amino JSON encoder. ### Improvements From 9dca1d95a87fd0d92cf95f389d0603d88bb34081 Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Thu, 4 Apr 2024 16:22:58 +0200 Subject: [PATCH 3/4] Add JSON validity check to cosmosInlineJSON --- x/tx/signing/aminojson/encoder.go | 12 ++++++------ x/tx/signing/aminojson/encoder_test.go | 18 ++++++++++-------- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/x/tx/signing/aminojson/encoder.go b/x/tx/signing/aminojson/encoder.go index fdd1f2310f34..d799eb52e627 100644 --- a/x/tx/signing/aminojson/encoder.go +++ b/x/tx/signing/aminojson/encoder.go @@ -82,7 +82,9 @@ func nullSliceAsEmptyEncoder(enc *Encoder, v protoreflect.Value, w io.Writer) er } // cosmosInlineJSON takes bytes and inlines them into a JSON document. -// This assumes the bytes contain valid JSON since otherwise the resulting document is invalid. +// +// This requires the bytes contain valid JSON since otherwise the resulting document would be invalid. +// Invalid JSON will result in an error. // // This replicates the behavior of JSON messages embedded in protobuf bytes // required for CosmWasm, e.g.: @@ -90,12 +92,10 @@ func nullSliceAsEmptyEncoder(enc *Encoder, v protoreflect.Value, w io.Writer) er func cosmosInlineJSON(_ *Encoder, v protoreflect.Value, w io.Writer) error { switch bz := v.Interface().(type) { case []byte: - // Caution, this does not include a validity check as json.RawMessage can be anything 🤷‍♂️ - blob, err := json.RawMessage(bz).MarshalJSON() - if err != nil { - return err + if !json.Valid(bz) { + return errors.New("invalid JSON bytes") } - _, err = w.Write(blob) + _, err := w.Write(bz) return err default: return fmt.Errorf("unsupported type %T", bz) diff --git a/x/tx/signing/aminojson/encoder_test.go b/x/tx/signing/aminojson/encoder_test.go index 3bfa301c0723..1ebf9990ac38 100644 --- a/x/tx/signing/aminojson/encoder_test.go +++ b/x/tx/signing/aminojson/encoder_test.go @@ -56,15 +56,17 @@ func TestCosmosInlineJSON(t *testing.T) { wantErr: false, wantOutput: `"hey yo"`, }, - // This test case is a bit tricky. Conceptually it makes no sense for this - // to pass. The question is just where the JSON validity check is done. - // In wasmd we have it in the message field validation. But it might make - // sense to move it here instead. - // For now it's better to consider this case undefined behaviour. "supported type - invalid JSON": { - value: protoreflect.ValueOfBytes([]byte(`foo`)), - wantErr: false, - wantOutput: `foo`, + value: protoreflect.ValueOfBytes([]byte(`foo`)), + wantErr: true, + }, + "supported type - invalid JSON (empty)": { + value: protoreflect.ValueOfBytes([]byte(``)), + wantErr: true, + }, + "supported type - invalid JSON (nil bytes)": { + value: protoreflect.ValueOfBytes(nil), + wantErr: true, }, "unsupported type - bool": { value: protoreflect.ValueOfBool(true), From 00bf1f02067f2075c275b0374c68d76d50a33dda Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Mon, 8 Apr 2024 09:37:10 +0200 Subject: [PATCH 4/4] Create test wrapper WithAJson and test --- .../aminojson/internal/testpb/test.proto | 4 + .../aminojson/internal/testpb/test.pulsar.go | 621 +++++++++++++++--- x/tx/signing/aminojson/json_marshal_test.go | 28 + 3 files changed, 579 insertions(+), 74 deletions(-) diff --git a/x/tx/signing/aminojson/internal/testpb/test.proto b/x/tx/signing/aminojson/internal/testpb/test.proto index 8be5a3dc1362..0bbb999426e6 100644 --- a/x/tx/signing/aminojson/internal/testpb/test.proto +++ b/x/tx/signing/aminojson/internal/testpb/test.proto @@ -20,6 +20,10 @@ message WithAList { repeated string list = 2; } +message WithAJson { + bytes field1 = 1 [(amino.encoding) = "inline_json"]; +} + message ABitOfEverything { option (amino.name) = "ABitOfEverything"; diff --git a/x/tx/signing/aminojson/internal/testpb/test.pulsar.go b/x/tx/signing/aminojson/internal/testpb/test.pulsar.go index 7cc06a47766e..0adf0b573d60 100644 --- a/x/tx/signing/aminojson/internal/testpb/test.pulsar.go +++ b/x/tx/signing/aminojson/internal/testpb/test.pulsar.go @@ -1286,6 +1286,428 @@ func (x *fastReflection_WithAList) ProtoMethods() *protoiface.Methods { } } +var ( + md_WithAJson protoreflect.MessageDescriptor + fd_WithAJson_field1 protoreflect.FieldDescriptor +) + +func init() { + file_testpb_test_proto_init() + md_WithAJson = File_testpb_test_proto.Messages().ByName("WithAJson") + fd_WithAJson_field1 = md_WithAJson.Fields().ByName("field1") +} + +var _ protoreflect.Message = (*fastReflection_WithAJson)(nil) + +type fastReflection_WithAJson WithAJson + +func (x *WithAJson) ProtoReflect() protoreflect.Message { + return (*fastReflection_WithAJson)(x) +} + +func (x *WithAJson) slowProtoReflect() protoreflect.Message { + mi := &file_testpb_test_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +var _fastReflection_WithAJson_messageType fastReflection_WithAJson_messageType +var _ protoreflect.MessageType = fastReflection_WithAJson_messageType{} + +type fastReflection_WithAJson_messageType struct{} + +func (x fastReflection_WithAJson_messageType) Zero() protoreflect.Message { + return (*fastReflection_WithAJson)(nil) +} +func (x fastReflection_WithAJson_messageType) New() protoreflect.Message { + return new(fastReflection_WithAJson) +} +func (x fastReflection_WithAJson_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_WithAJson +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_WithAJson) Descriptor() protoreflect.MessageDescriptor { + return md_WithAJson +} + +// Type returns the message type, which encapsulates both Go and protobuf +// type information. If the Go type information is not needed, +// it is recommended that the message descriptor be used instead. +func (x *fastReflection_WithAJson) Type() protoreflect.MessageType { + return _fastReflection_WithAJson_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_WithAJson) New() protoreflect.Message { + return new(fastReflection_WithAJson) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_WithAJson) Interface() protoreflect.ProtoMessage { + return (*WithAJson)(x) +} + +// Range iterates over every populated field in an undefined order, +// calling f for each field descriptor and value encountered. +// Range returns immediately if f returns false. +// While iterating, mutating operations may only be performed +// on the current field descriptor. +func (x *fastReflection_WithAJson) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { + if len(x.Field1) != 0 { + value := protoreflect.ValueOfBytes(x.Field1) + if !f(fd_WithAJson_field1, value) { + return + } + } +} + +// Has reports whether a field is populated. +// +// Some fields have the property of nullability where it is possible to +// distinguish between the default value of a field and whether the field +// was explicitly populated with the default value. Singular message fields, +// member fields of a oneof, and proto2 scalar fields are nullable. Such +// fields are populated only if explicitly set. +// +// In other cases (aside from the nullable cases above), +// a proto3 scalar field is populated if it contains a non-zero value, and +// a repeated field is populated if it is non-empty. +func (x *fastReflection_WithAJson) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + case "testpb.WithAJson.field1": + return len(x.Field1) != 0 + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: testpb.WithAJson")) + } + panic(fmt.Errorf("message testpb.WithAJson does not contain field %s", fd.FullName())) + } +} + +// Clear clears the field such that a subsequent Has call reports false. +// +// Clearing an extension field clears both the extension type and value +// associated with the given field number. +// +// Clear is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_WithAJson) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + case "testpb.WithAJson.field1": + x.Field1 = nil + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: testpb.WithAJson")) + } + panic(fmt.Errorf("message testpb.WithAJson does not contain field %s", fd.FullName())) + } +} + +// Get retrieves the value for a field. +// +// For unpopulated scalars, it returns the default value, where +// the default value of a bytes scalar is guaranteed to be a copy. +// For unpopulated composite types, it returns an empty, read-only view +// of the value; to obtain a mutable reference, use Mutable. +func (x *fastReflection_WithAJson) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + case "testpb.WithAJson.field1": + value := x.Field1 + return protoreflect.ValueOfBytes(value) + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: testpb.WithAJson")) + } + panic(fmt.Errorf("message testpb.WithAJson does not contain field %s", descriptor.FullName())) + } +} + +// Set stores the value for a field. +// +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType. +// When setting a composite type, it is unspecified whether the stored value +// aliases the source's memory in any way. If the composite value is an +// empty, read-only value, then it panics. +// +// Set is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_WithAJson) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + case "testpb.WithAJson.field1": + x.Field1 = value.Bytes() + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: testpb.WithAJson")) + } + panic(fmt.Errorf("message testpb.WithAJson does not contain field %s", fd.FullName())) + } +} + +// Mutable returns a mutable reference to a composite type. +// +// If the field is unpopulated, it may allocate a composite value. +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType +// if not already stored. +// It panics if the field does not contain a composite type. +// +// Mutable is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_WithAJson) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "testpb.WithAJson.field1": + panic(fmt.Errorf("field field1 of message testpb.WithAJson is not mutable")) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: testpb.WithAJson")) + } + panic(fmt.Errorf("message testpb.WithAJson does not contain field %s", fd.FullName())) + } +} + +// NewField returns a new value that is assignable to the field +// for the given descriptor. For scalars, this returns the default value. +// For lists, maps, and messages, this returns a new, empty, mutable value. +func (x *fastReflection_WithAJson) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "testpb.WithAJson.field1": + return protoreflect.ValueOfBytes(nil) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: testpb.WithAJson")) + } + panic(fmt.Errorf("message testpb.WithAJson does not contain field %s", fd.FullName())) + } +} + +// WhichOneof reports which field within the oneof is populated, +// returning nil if none are populated. +// It panics if the oneof descriptor does not belong to this message. +func (x *fastReflection_WithAJson) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in testpb.WithAJson", d.FullName())) + } + panic("unreachable") +} + +// GetUnknown retrieves the entire list of unknown fields. +// The caller may only mutate the contents of the RawFields +// if the mutated bytes are stored back into the message with SetUnknown. +func (x *fastReflection_WithAJson) GetUnknown() protoreflect.RawFields { + return x.unknownFields +} + +// SetUnknown stores an entire list of unknown fields. +// The raw fields must be syntactically valid according to the wire format. +// An implementation may panic if this is not the case. +// Once stored, the caller must not mutate the content of the RawFields. +// An empty RawFields may be passed to clear the fields. +// +// SetUnknown is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_WithAJson) SetUnknown(fields protoreflect.RawFields) { + x.unknownFields = fields +} + +// IsValid reports whether the message is valid. +// +// An invalid message is an empty, read-only value. +// +// An invalid message often corresponds to a nil pointer of the concrete +// message type, but the details are implementation dependent. +// Validity is not part of the protobuf data model, and may not +// be preserved in marshaling or other operations. +func (x *fastReflection_WithAJson) IsValid() bool { + return x != nil +} + +// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. +// This method may return nil. +// +// The returned methods type is identical to +// "google.golang.org/protobuf/runtime/protoiface".Methods. +// Consult the protoiface package documentation for details. +func (x *fastReflection_WithAJson) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*WithAJson) + if x == nil { + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: 0, + } + } + options := runtime.SizeInputToOptions(input) + _ = options + var n int + var l int + _ = l + l = len(x.Field1) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + if x.unknownFields != nil { + n += len(x.unknownFields) + } + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: n, + } + } + + marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { + x := input.Message.Interface().(*WithAJson) + if x == nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + options := runtime.MarshalInputToOptions(input) + _ = options + size := options.Size(x) + dAtA := make([]byte, size) + i := len(dAtA) + _ = i + var l int + _ = l + if x.unknownFields != nil { + i -= len(x.unknownFields) + copy(dAtA[i:], x.unknownFields) + } + if len(x.Field1) > 0 { + i -= len(x.Field1) + copy(dAtA[i:], x.Field1) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Field1))) + i-- + dAtA[i] = 0xa + } + if input.Buf != nil { + input.Buf = append(input.Buf, dAtA...) + } else { + input.Buf = dAtA + } + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { + x := input.Message.Interface().(*WithAJson) + if x == nil { + return protoiface.UnmarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Flags: input.Flags, + }, nil + } + options := runtime.UnmarshalInputToOptions(input) + _ = options + dAtA := input.Buf + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: WithAJson: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: WithAJson: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Field1", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Field1 = append(x.Field1[:0], dAtA[iNdEx:postIndex]...) + if x.Field1 == nil { + x.Field1 = []byte{} + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := runtime.Skip(dAtA[iNdEx:]) + if err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if !options.DiscardUnknown { + x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + } + iNdEx += skippy + } + } + + if iNdEx > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil + } + return &protoiface.Methods{ + NoUnkeyedLiterals: struct{}{}, + Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, + Size: size, + Marshal: marshal, + Unmarshal: unmarshal, + Merge: nil, + CheckInitialized: nil, + } +} + var _ protoreflect.List = (*_ABitOfEverything_6_list)(nil) type _ABitOfEverything_6_list struct { @@ -1382,7 +1804,7 @@ func (x *ABitOfEverything) ProtoReflect() protoreflect.Message { } func (x *ABitOfEverything) slowProtoReflect() protoreflect.Message { - mi := &file_testpb_test_proto_msgTypes[2] + mi := &file_testpb_test_proto_msgTypes[3] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2616,7 +3038,7 @@ func (x *Duration) ProtoReflect() protoreflect.Message { } func (x *Duration) slowProtoReflect() protoreflect.Message { - mi := &file_testpb_test_proto_msgTypes[3] + mi := &file_testpb_test_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3130,7 +3552,7 @@ func (x *NestedMessage) ProtoReflect() protoreflect.Message { } func (x *NestedMessage) slowProtoReflect() protoreflect.Message { - mi := &file_testpb_test_proto_msgTypes[4] + mi := &file_testpb_test_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3716,6 +4138,41 @@ func (x *WithAList) GetList() []string { return nil } +type WithAJson struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Field1 []byte `protobuf:"bytes,1,opt,name=field1,proto3" json:"field1,omitempty"` +} + +func (x *WithAJson) Reset() { + *x = WithAJson{} + if protoimpl.UnsafeEnabled { + mi := &file_testpb_test_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *WithAJson) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*WithAJson) ProtoMessage() {} + +// Deprecated: Use WithAJson.ProtoReflect.Descriptor instead. +func (*WithAJson) Descriptor() ([]byte, []int) { + return file_testpb_test_proto_rawDescGZIP(), []int{2} +} + +func (x *WithAJson) GetField1() []byte { + if x != nil { + return x.Field1 + } + return nil +} + type ABitOfEverything struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -3742,7 +4199,7 @@ type ABitOfEverything struct { func (x *ABitOfEverything) Reset() { *x = ABitOfEverything{} if protoimpl.UnsafeEnabled { - mi := &file_testpb_test_proto_msgTypes[2] + mi := &file_testpb_test_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3756,7 +4213,7 @@ func (*ABitOfEverything) ProtoMessage() {} // Deprecated: Use ABitOfEverything.ProtoReflect.Descriptor instead. func (*ABitOfEverything) Descriptor() ([]byte, []int) { - return file_testpb_test_proto_rawDescGZIP(), []int{2} + return file_testpb_test_proto_rawDescGZIP(), []int{3} } func (x *ABitOfEverything) GetMessage() *NestedMessage { @@ -3883,7 +4340,7 @@ type Duration struct { func (x *Duration) Reset() { *x = Duration{} if protoimpl.UnsafeEnabled { - mi := &file_testpb_test_proto_msgTypes[3] + mi := &file_testpb_test_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3897,7 +4354,7 @@ func (*Duration) ProtoMessage() {} // Deprecated: Use Duration.ProtoReflect.Descriptor instead. func (*Duration) Descriptor() ([]byte, []int) { - return file_testpb_test_proto_rawDescGZIP(), []int{3} + return file_testpb_test_proto_rawDescGZIP(), []int{4} } func (x *Duration) GetDuration() *durationpb.Duration { @@ -3926,7 +4383,7 @@ type NestedMessage struct { func (x *NestedMessage) Reset() { *x = NestedMessage{} if protoimpl.UnsafeEnabled { - mi := &file_testpb_test_proto_msgTypes[4] + mi := &file_testpb_test_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3940,7 +4397,7 @@ func (*NestedMessage) ProtoMessage() {} // Deprecated: Use NestedMessage.ProtoReflect.Descriptor instead. func (*NestedMessage) Descriptor() ([]byte, []int) { - return file_testpb_test_proto_rawDescGZIP(), []int{4} + return file_testpb_test_proto_rawDescGZIP(), []int{5} } func (x *NestedMessage) GetFoo() string { @@ -3989,57 +4446,60 @@ var file_testpb_test_proto_rawDesc = []byte{ 0x6d, 0x70, 0x74, 0x79, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x42, 0x05, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x11, 0x64, 0x6f, 0x6e, 0x74, 0x4f, 0x6d, 0x69, 0x74, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x73, - 0x74, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x6c, 0x69, 0x73, 0x74, 0x22, 0x92, 0x03, - 0x0a, 0x10, 0x41, 0x42, 0x69, 0x74, 0x4f, 0x66, 0x45, 0x76, 0x65, 0x72, 0x79, 0x74, 0x68, 0x69, - 0x6e, 0x67, 0x12, 0x2f, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x62, 0x2e, 0x4e, 0x65, 0x73, - 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, - 0x61, 0x67, 0x65, 0x12, 0x22, 0x0a, 0x04, 0x65, 0x6e, 0x75, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0e, 0x32, 0x0e, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x62, 0x2e, 0x41, 0x6e, 0x45, 0x6e, 0x75, - 0x6d, 0x52, 0x04, 0x65, 0x6e, 0x75, 0x6d, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x70, 0x65, 0x61, - 0x74, 0x65, 0x64, 0x18, 0x06, 0x20, 0x03, 0x28, 0x05, 0x52, 0x08, 0x72, 0x65, 0x70, 0x65, 0x61, - 0x74, 0x65, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x74, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x03, 0x73, 0x74, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x62, 0x6f, 0x6f, 0x6c, 0x18, 0x08, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x04, 0x62, 0x6f, 0x6f, 0x6c, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x79, 0x74, - 0x65, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x12, - 0x10, 0x0a, 0x03, 0x69, 0x33, 0x32, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x69, 0x33, - 0x32, 0x12, 0x10, 0x0a, 0x03, 0x66, 0x33, 0x32, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x07, 0x52, 0x03, - 0x66, 0x33, 0x32, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x33, 0x32, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0d, - 0x52, 0x03, 0x75, 0x33, 0x32, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x33, 0x32, 0x18, 0x0d, 0x20, - 0x01, 0x28, 0x11, 0x52, 0x04, 0x73, 0x69, 0x33, 0x32, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x66, 0x33, - 0x32, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0f, 0x52, 0x04, 0x73, 0x66, 0x33, 0x32, 0x12, 0x10, 0x0a, - 0x03, 0x69, 0x36, 0x34, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x03, 0x52, 0x03, 0x69, 0x36, 0x34, 0x12, - 0x10, 0x0a, 0x03, 0x66, 0x36, 0x34, 0x18, 0x10, 0x20, 0x01, 0x28, 0x06, 0x52, 0x03, 0x66, 0x36, - 0x34, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x36, 0x34, 0x18, 0x11, 0x20, 0x01, 0x28, 0x04, 0x52, 0x03, - 0x75, 0x36, 0x34, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x36, 0x34, 0x18, 0x12, 0x20, 0x01, 0x28, - 0x12, 0x52, 0x04, 0x73, 0x69, 0x36, 0x34, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x66, 0x36, 0x34, 0x18, - 0x13, 0x20, 0x01, 0x28, 0x10, 0x52, 0x04, 0x73, 0x66, 0x36, 0x34, 0x3a, 0x15, 0x8a, 0xe7, 0xb0, - 0x2a, 0x10, 0x41, 0x42, 0x69, 0x74, 0x4f, 0x66, 0x45, 0x76, 0x65, 0x72, 0x79, 0x74, 0x68, 0x69, - 0x6e, 0x67, 0x22, 0x7b, 0x0a, 0x08, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x35, - 0x0a, 0x08, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x64, 0x75, 0x72, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x38, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, - 0x6d, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, - 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, - 0x47, 0x0a, 0x0d, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x12, 0x10, 0x0a, 0x03, 0x66, 0x6f, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x66, - 0x6f, 0x6f, 0x12, 0x10, 0x0a, 0x03, 0x62, 0x61, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, - 0x03, 0x62, 0x61, 0x72, 0x3a, 0x12, 0x8a, 0xe7, 0xb0, 0x2a, 0x0d, 0x4e, 0x65, 0x73, 0x74, 0x65, - 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2a, 0x29, 0x0a, 0x06, 0x41, 0x6e, 0x45, 0x6e, - 0x75, 0x6d, 0x12, 0x0d, 0x0a, 0x09, 0x55, 0x4e, 0x44, 0x45, 0x46, 0x49, 0x4e, 0x45, 0x44, 0x10, - 0x00, 0x12, 0x07, 0x0a, 0x03, 0x4f, 0x4e, 0x45, 0x10, 0x01, 0x12, 0x07, 0x0a, 0x03, 0x54, 0x57, - 0x4f, 0x10, 0x02, 0x42, 0x83, 0x01, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x2e, 0x74, 0x65, 0x73, 0x74, - 0x70, 0x62, 0x42, 0x09, 0x54, 0x65, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, - 0x32, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x78, 0x2f, - 0x74, 0x78, 0x2f, 0x61, 0x6d, 0x69, 0x6e, 0x6f, 0x6a, 0x73, 0x6f, 0x6e, 0x2f, 0x69, 0x6e, 0x74, - 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x70, 0x62, 0x2f, 0x74, 0x65, 0x73, - 0x74, 0x70, 0x62, 0xa2, 0x02, 0x03, 0x54, 0x58, 0x58, 0xaa, 0x02, 0x06, 0x54, 0x65, 0x73, 0x74, - 0x70, 0x62, 0xca, 0x02, 0x06, 0x54, 0x65, 0x73, 0x74, 0x70, 0x62, 0xe2, 0x02, 0x12, 0x54, 0x65, - 0x73, 0x74, 0x70, 0x62, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, - 0xea, 0x02, 0x06, 0x54, 0x65, 0x73, 0x74, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x33, + 0x74, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x6c, 0x69, 0x73, 0x74, 0x22, 0x35, 0x0a, + 0x09, 0x57, 0x69, 0x74, 0x68, 0x41, 0x4a, 0x73, 0x6f, 0x6e, 0x12, 0x28, 0x0a, 0x06, 0x66, 0x69, + 0x65, 0x6c, 0x64, 0x31, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x10, 0x9a, 0xe7, 0xb0, 0x2a, + 0x0b, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x5f, 0x6a, 0x73, 0x6f, 0x6e, 0x52, 0x06, 0x66, 0x69, + 0x65, 0x6c, 0x64, 0x31, 0x22, 0x92, 0x03, 0x0a, 0x10, 0x41, 0x42, 0x69, 0x74, 0x4f, 0x66, 0x45, + 0x76, 0x65, 0x72, 0x79, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x12, 0x2f, 0x0a, 0x07, 0x6d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x65, 0x73, + 0x74, 0x70, 0x62, 0x2e, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x22, 0x0a, 0x04, 0x65, 0x6e, + 0x75, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0e, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, + 0x62, 0x2e, 0x41, 0x6e, 0x45, 0x6e, 0x75, 0x6d, 0x52, 0x04, 0x65, 0x6e, 0x75, 0x6d, 0x12, 0x1a, + 0x0a, 0x08, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x18, 0x06, 0x20, 0x03, 0x28, 0x05, + 0x52, 0x08, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x74, + 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x73, 0x74, 0x72, 0x12, 0x12, 0x0a, 0x04, + 0x62, 0x6f, 0x6f, 0x6c, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x62, 0x6f, 0x6f, 0x6c, + 0x12, 0x14, 0x0a, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x69, 0x33, 0x32, 0x18, 0x0a, 0x20, + 0x01, 0x28, 0x05, 0x52, 0x03, 0x69, 0x33, 0x32, 0x12, 0x10, 0x0a, 0x03, 0x66, 0x33, 0x32, 0x18, + 0x0b, 0x20, 0x01, 0x28, 0x07, 0x52, 0x03, 0x66, 0x33, 0x32, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x33, + 0x32, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x75, 0x33, 0x32, 0x12, 0x12, 0x0a, 0x04, + 0x73, 0x69, 0x33, 0x32, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x11, 0x52, 0x04, 0x73, 0x69, 0x33, 0x32, + 0x12, 0x12, 0x0a, 0x04, 0x73, 0x66, 0x33, 0x32, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0f, 0x52, 0x04, + 0x73, 0x66, 0x33, 0x32, 0x12, 0x10, 0x0a, 0x03, 0x69, 0x36, 0x34, 0x18, 0x0f, 0x20, 0x01, 0x28, + 0x03, 0x52, 0x03, 0x69, 0x36, 0x34, 0x12, 0x10, 0x0a, 0x03, 0x66, 0x36, 0x34, 0x18, 0x10, 0x20, + 0x01, 0x28, 0x06, 0x52, 0x03, 0x66, 0x36, 0x34, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x36, 0x34, 0x18, + 0x11, 0x20, 0x01, 0x28, 0x04, 0x52, 0x03, 0x75, 0x36, 0x34, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, + 0x36, 0x34, 0x18, 0x12, 0x20, 0x01, 0x28, 0x12, 0x52, 0x04, 0x73, 0x69, 0x36, 0x34, 0x12, 0x12, + 0x0a, 0x04, 0x73, 0x66, 0x36, 0x34, 0x18, 0x13, 0x20, 0x01, 0x28, 0x10, 0x52, 0x04, 0x73, 0x66, + 0x36, 0x34, 0x3a, 0x15, 0x8a, 0xe7, 0xb0, 0x2a, 0x10, 0x41, 0x42, 0x69, 0x74, 0x4f, 0x66, 0x45, + 0x76, 0x65, 0x72, 0x79, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x22, 0x7b, 0x0a, 0x08, 0x44, 0x75, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x35, 0x0a, 0x08, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x52, 0x08, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x38, 0x0a, 0x09, + 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x74, 0x69, 0x6d, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0x47, 0x0a, 0x0d, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x66, 0x6f, 0x6f, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x66, 0x6f, 0x6f, 0x12, 0x10, 0x0a, 0x03, 0x62, 0x61, 0x72, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x62, 0x61, 0x72, 0x3a, 0x12, 0x8a, 0xe7, 0xb0, + 0x2a, 0x0d, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2a, + 0x29, 0x0a, 0x06, 0x41, 0x6e, 0x45, 0x6e, 0x75, 0x6d, 0x12, 0x0d, 0x0a, 0x09, 0x55, 0x4e, 0x44, + 0x45, 0x46, 0x49, 0x4e, 0x45, 0x44, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x4f, 0x4e, 0x45, 0x10, + 0x01, 0x12, 0x07, 0x0a, 0x03, 0x54, 0x57, 0x4f, 0x10, 0x02, 0x42, 0x83, 0x01, 0x0a, 0x0a, 0x63, + 0x6f, 0x6d, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x62, 0x42, 0x09, 0x54, 0x65, 0x73, 0x74, 0x50, + 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x32, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, + 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x78, 0x2f, 0x74, 0x78, 0x2f, 0x61, 0x6d, 0x69, 0x6e, 0x6f, 0x6a, + 0x73, 0x6f, 0x6e, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x73, + 0x74, 0x70, 0x62, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x70, 0x62, 0xa2, 0x02, 0x03, 0x54, 0x58, 0x58, + 0xaa, 0x02, 0x06, 0x54, 0x65, 0x73, 0x74, 0x70, 0x62, 0xca, 0x02, 0x06, 0x54, 0x65, 0x73, 0x74, + 0x70, 0x62, 0xe2, 0x02, 0x12, 0x54, 0x65, 0x73, 0x74, 0x70, 0x62, 0x5c, 0x47, 0x50, 0x42, 0x4d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x06, 0x54, 0x65, 0x73, 0x74, 0x70, 0x62, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -4055,24 +4515,25 @@ func file_testpb_test_proto_rawDescGZIP() []byte { } var file_testpb_test_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_testpb_test_proto_msgTypes = make([]protoimpl.MessageInfo, 6) +var file_testpb_test_proto_msgTypes = make([]protoimpl.MessageInfo, 7) var file_testpb_test_proto_goTypes = []interface{}{ (AnEnum)(0), // 0: testpb.AnEnum (*WithAMap)(nil), // 1: testpb.WithAMap (*WithAList)(nil), // 2: testpb.WithAList - (*ABitOfEverything)(nil), // 3: testpb.ABitOfEverything - (*Duration)(nil), // 4: testpb.Duration - (*NestedMessage)(nil), // 5: testpb.NestedMessage - nil, // 6: testpb.WithAMap.StrMapEntry - (*durationpb.Duration)(nil), // 7: google.protobuf.Duration - (*timestamppb.Timestamp)(nil), // 8: google.protobuf.Timestamp + (*WithAJson)(nil), // 3: testpb.WithAJson + (*ABitOfEverything)(nil), // 4: testpb.ABitOfEverything + (*Duration)(nil), // 5: testpb.Duration + (*NestedMessage)(nil), // 6: testpb.NestedMessage + nil, // 7: testpb.WithAMap.StrMapEntry + (*durationpb.Duration)(nil), // 8: google.protobuf.Duration + (*timestamppb.Timestamp)(nil), // 9: google.protobuf.Timestamp } var file_testpb_test_proto_depIdxs = []int32{ - 6, // 0: testpb.WithAMap.str_map:type_name -> testpb.WithAMap.StrMapEntry - 5, // 1: testpb.ABitOfEverything.message:type_name -> testpb.NestedMessage + 7, // 0: testpb.WithAMap.str_map:type_name -> testpb.WithAMap.StrMapEntry + 6, // 1: testpb.ABitOfEverything.message:type_name -> testpb.NestedMessage 0, // 2: testpb.ABitOfEverything.enum:type_name -> testpb.AnEnum - 7, // 3: testpb.Duration.duration:type_name -> google.protobuf.Duration - 8, // 4: testpb.Duration.timestamp:type_name -> google.protobuf.Timestamp + 8, // 3: testpb.Duration.duration:type_name -> google.protobuf.Duration + 9, // 4: testpb.Duration.timestamp:type_name -> google.protobuf.Timestamp 5, // [5:5] is the sub-list for method output_type 5, // [5:5] is the sub-list for method input_type 5, // [5:5] is the sub-list for extension type_name @@ -4111,7 +4572,7 @@ func file_testpb_test_proto_init() { } } file_testpb_test_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ABitOfEverything); i { + switch v := v.(*WithAJson); i { case 0: return &v.state case 1: @@ -4123,7 +4584,7 @@ func file_testpb_test_proto_init() { } } file_testpb_test_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Duration); i { + switch v := v.(*ABitOfEverything); i { case 0: return &v.state case 1: @@ -4135,6 +4596,18 @@ func file_testpb_test_proto_init() { } } file_testpb_test_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Duration); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_testpb_test_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*NestedMessage); i { case 0: return &v.state @@ -4153,7 +4626,7 @@ func file_testpb_test_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_testpb_test_proto_rawDesc, NumEnums: 1, - NumMessages: 6, + NumMessages: 7, NumExtensions: 0, NumServices: 0, }, diff --git a/x/tx/signing/aminojson/json_marshal_test.go b/x/tx/signing/aminojson/json_marshal_test.go index be8caf8c7364..a51b83bb49da 100644 --- a/x/tx/signing/aminojson/json_marshal_test.go +++ b/x/tx/signing/aminojson/json_marshal_test.go @@ -210,6 +210,34 @@ func TestMarshalDuration(t *testing.T) { require.Equal(t, `{"duration":"1s"}`, string(bz)) } +func TestWithAJson(t *testing.T) { + encoder := aminojson.NewEncoder(aminojson.EncoderOptions{}) + + // list + msg := &testpb.WithAJson{ + Field1: []byte(`[{"name":"child1"}]`), + } + bz, err := encoder.Marshal(msg) + require.NoError(t, err) + require.Equal(t, `{"field1":[{"name":"child1"}]}`, string(bz)) + + // string + msg = &testpb.WithAJson{ + Field1: []byte(`"hello again"`), + } + bz, err = encoder.Marshal(msg) + require.NoError(t, err) + require.Equal(t, `{"field1":"hello again"}`, string(bz)) + + // object + msg = &testpb.WithAJson{ + Field1: []byte(`{"deeper":{"nesting":1}}`), + } + bz, err = encoder.Marshal(msg) + require.NoError(t, err) + require.Equal(t, `{"field1":{"deeper":{"nesting":1}}}`, string(bz)) +} + func TestIndent(t *testing.T) { encoder := aminojson.NewEncoder(aminojson.EncoderOptions{Indent: " "})