converter.go 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. // Copyright 2022 EMQ Technologies Co., Ltd.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package protobuf
  15. import (
  16. "fmt"
  17. "github.com/jhump/protoreflect/desc"
  18. "github.com/jhump/protoreflect/desc/protoparse"
  19. "github.com/lf-edge/ekuiper/internal/converter/static"
  20. "github.com/lf-edge/ekuiper/pkg/message"
  21. )
  22. type Converter struct {
  23. descriptor *desc.MessageDescriptor
  24. fc *FieldConverter
  25. }
  26. var protoParser *protoparse.Parser
  27. func init() {
  28. protoParser = &protoparse.Parser{}
  29. }
  30. func NewConverter(schemaFile string, soFile string, messageName string) (message.Converter, error) {
  31. if soFile != "" {
  32. return static.LoadStaticConverter(soFile, messageName)
  33. } else {
  34. if fds, err := protoParser.ParseFiles(schemaFile); err != nil {
  35. return nil, fmt.Errorf("parse schema file %s failed: %s", schemaFile, err)
  36. } else {
  37. messageDescriptor := fds[0].FindMessage(messageName)
  38. if messageDescriptor == nil {
  39. return nil, fmt.Errorf("message type %s not found in schema file %s", messageName, schemaFile)
  40. }
  41. return &Converter{
  42. descriptor: messageDescriptor,
  43. fc: GetFieldConverter(),
  44. }, nil
  45. }
  46. }
  47. }
  48. func (c *Converter) Encode(d interface{}) ([]byte, error) {
  49. switch m := d.(type) {
  50. case map[string]interface{}:
  51. msg, err := c.fc.encodeMap(c.descriptor, m)
  52. if err != nil {
  53. return nil, err
  54. }
  55. return msg.Marshal()
  56. default:
  57. return nil, fmt.Errorf("unsupported type %v, must be a map", d)
  58. }
  59. }
  60. func (c *Converter) Decode(b []byte) (interface{}, error) {
  61. result := mf.NewDynamicMessage(c.descriptor)
  62. err := result.Unmarshal(b)
  63. if err != nil {
  64. return nil, err
  65. }
  66. return c.fc.DecodeMessage(result, c.descriptor), nil
  67. }