package pb import ( "bytes" "fmt" "strings" "github.com/VictoriaMetrics/easyproto" ) // Resource represents the corresponding OTEL protobuf message type Resource struct { Attributes []*KeyValue } // marshalProtobuf marshals func (r *Resource) marshalProtobuf(mm *easyproto.MessageMarshaler) { for _, a := range r.Attributes { a.marshalProtobuf(mm.AppendMessage(1)) } } // unmarshalProtobuf unmarshals r from protobuf message at src. func (r *Resource) unmarshalProtobuf(src []byte) (err error) { // message Resource { // repeated KeyValue attributes = 1; // } var fc easyproto.FieldContext for len(src) > 0 { src, err = fc.NextField(src) if err != nil { return fmt.Errorf("cannot read next field in Resource: %w", err) } switch fc.FieldNum { case 1: data, ok := fc.MessageData() if !ok { return fmt.Errorf("cannot read Attribute data") } r.Attributes = append(r.Attributes, &KeyValue{}) a := r.Attributes[len(r.Attributes)-1] if err := a.unmarshalProtobuf(data); err != nil { return fmt.Errorf("cannot unmarshal Attribute: %w", err) } } } return nil } // KeyValue represents the corresponding OTEL protobuf message type KeyValue struct { Key string Value *AnyValue } func (kv *KeyValue) marshalProtobuf(mm *easyproto.MessageMarshaler) { mm.AppendString(1, kv.Key) if kv.Value != nil { kv.Value.marshalProtobuf(mm.AppendMessage(2)) } } // unmarshalProtobuf unmarshals kv from protobuf message at src. func (kv *KeyValue) unmarshalProtobuf(src []byte) (err error) { // message KeyValue { // string key = 1; // AnyValue value = 2; // } var fc easyproto.FieldContext for len(src) > 0 { src, err = fc.NextField(src) if err != nil { return fmt.Errorf("cannot read next field in KeyValue: %w", err) } switch fc.FieldNum { case 1: key, ok := fc.String() if !ok { return fmt.Errorf("cannot read Key") } kv.Key = strings.Clone(key) case 2: data, ok := fc.MessageData() if !ok { return fmt.Errorf("cannot read Value") } kv.Value = &AnyValue{} if err := kv.Value.unmarshalProtobuf(data); err != nil { return fmt.Errorf("cannot unmarshal Value: %w", err) } } } return nil } // AnyValue represents the corresponding OTEL protobuf message type AnyValue struct { StringValue *string BoolValue *bool IntValue *int64 DoubleValue *float64 ArrayValue *ArrayValue KeyValueList *KeyValueList BytesValue *[]byte } func (av *AnyValue) marshalProtobuf(mm *easyproto.MessageMarshaler) { switch { case av.StringValue != nil: mm.AppendString(1, *av.StringValue) case av.BoolValue != nil: mm.AppendBool(2, *av.BoolValue) case av.IntValue != nil: mm.AppendInt64(3, *av.IntValue) case av.DoubleValue != nil: mm.AppendDouble(4, *av.DoubleValue) case av.ArrayValue != nil: av.ArrayValue.marshalProtobuf(mm.AppendMessage(5)) case av.KeyValueList != nil: av.KeyValueList.marshalProtobuf(mm.AppendMessage(6)) case av.BytesValue != nil: mm.AppendBytes(7, *av.BytesValue) } } // unmarshalProtobuf unmarshals av from protobuf message at src. func (av *AnyValue) unmarshalProtobuf(src []byte) (err error) { // message AnyValue { // oneof value { // string string_value = 1; // bool bool_value = 2; // int64 int_value = 3; // double double_value = 4; // ArrayValue array_value = 5; // KeyValueList kvlist_value = 6; // bytes bytes_value = 7; // } // } var fc easyproto.FieldContext for len(src) > 0 { src, err = fc.NextField(src) if err != nil { return fmt.Errorf("cannot read next field in AnyValue") } switch fc.FieldNum { case 1: stringValue, ok := fc.String() if !ok { return fmt.Errorf("cannot read StringValue") } stringValue = strings.Clone(stringValue) av.StringValue = &stringValue case 2: boolValue, ok := fc.Bool() if !ok { return fmt.Errorf("cannot read BoolValue") } av.BoolValue = &boolValue case 3: intValue, ok := fc.Int64() if !ok { return fmt.Errorf("cannot read IntValue") } av.IntValue = &intValue case 4: doubleValue, ok := fc.Double() if !ok { return fmt.Errorf("cannot read DoubleValue") } av.DoubleValue = &doubleValue case 5: data, ok := fc.MessageData() if !ok { return fmt.Errorf("cannot read ArrayValue") } av.ArrayValue = &ArrayValue{} if err := av.ArrayValue.unmarshalProtobuf(data); err != nil { return fmt.Errorf("cannot unmarshal ArrayValue: %w", err) } case 6: data, ok := fc.MessageData() if !ok { return fmt.Errorf("cannot read KeyValueList") } av.KeyValueList = &KeyValueList{} if err := av.KeyValueList.unmarshalProtobuf(data); err != nil { return fmt.Errorf("cannot unmarshal KeyValueList: %w", err) } case 7: bytesValue, ok := fc.Bytes() if !ok { return fmt.Errorf("cannot read BytesValue") } bytesValue = bytes.Clone(bytesValue) av.BytesValue = &bytesValue } } return nil } // ArrayValue represents the corresponding OTEL protobuf message type ArrayValue struct { Values []*AnyValue } func (av *ArrayValue) marshalProtobuf(mm *easyproto.MessageMarshaler) { for _, v := range av.Values { v.marshalProtobuf(mm.AppendMessage(1)) } } // unmarshalProtobuf unmarshals av from protobuf message at src. func (av *ArrayValue) unmarshalProtobuf(src []byte) (err error) { // message ArrayValue { // repeated AnyValue values = 1; // } var fc easyproto.FieldContext for len(src) > 0 { src, err = fc.NextField(src) if err != nil { return fmt.Errorf("cannot read next field in ArrayValue") } switch fc.FieldNum { case 1: data, ok := fc.MessageData() if !ok { return fmt.Errorf("cannot read Value data") } av.Values = append(av.Values, &AnyValue{}) v := av.Values[len(av.Values)-1] if err := v.unmarshalProtobuf(data); err != nil { return fmt.Errorf("cannot unmarshal Value: %w", err) } } } return nil } // KeyValueList represents the corresponding OTEL protobuf message type KeyValueList struct { Values []*KeyValue } func (kvl *KeyValueList) marshalProtobuf(mm *easyproto.MessageMarshaler) { for _, v := range kvl.Values { v.marshalProtobuf(mm.AppendMessage(1)) } } // unmarshalProtobuf unmarshals kvl from protobuf message at src. func (kvl *KeyValueList) unmarshalProtobuf(src []byte) (err error) { // message KeyValueList { // repeated KeyValue values = 1; // } var fc easyproto.FieldContext for len(src) > 0 { src, err = fc.NextField(src) if err != nil { return fmt.Errorf("cannot read next field in KeyValueList") } switch fc.FieldNum { case 1: data, ok := fc.MessageData() if !ok { return fmt.Errorf("cannot read Value data") } kvl.Values = append(kvl.Values, &KeyValue{}) v := kvl.Values[len(kvl.Values)-1] if err := v.unmarshalProtobuf(data); err != nil { return fmt.Errorf("cannot unmarshal Value: %w", err) } } } return nil }