github.com/Rookout/GoSDK@v0.1.48/pkg/processor/namespaces/namespace_serializer2.go (about)

     1  package namespaces
     2  
     3  import (
     4  	"reflect"
     5  	"time"
     6  	"unicode/utf8"
     7  	"unsafe"
     8  
     9  	"github.com/Rookout/GoSDK/pkg/config"
    10  	pb "github.com/Rookout/GoSDK/pkg/protobuf"
    11  	"github.com/Rookout/GoSDK/pkg/rookoutErrors"
    12  	"github.com/Rookout/GoSDK/pkg/utils"
    13  	"google.golang.org/protobuf/types/known/timestamppb"
    14  )
    15  
    16  type NamespaceSerializer2 struct {
    17  	*pb.Variant2
    18  	StringCache  map[string]uint32
    19  	logErrors    bool
    20  	currentDepth int
    21  }
    22  
    23  func NewNamespaceSerializer2(fromNamespace Namespace, logErrors bool) *NamespaceSerializer2 {
    24  	g := &NamespaceSerializer2{StringCache: make(map[string]uint32), Variant2: &pb.Variant2{}, logErrors: logErrors}
    25  	fromNamespace.Serialize(g)
    26  	return g
    27  }
    28  
    29  func (n *NamespaceSerializer2) spawn(fromNamespace Namespace) *NamespaceSerializer2 {
    30  	spawned := &NamespaceSerializer2{StringCache: n.StringCache, Variant2: &pb.Variant2{}, logErrors: n.logErrors, currentDepth: n.currentDepth + 1}
    31  
    32  	fromNamespace.Serialize(spawned)
    33  	return spawned
    34  }
    35  
    36  func (n *NamespaceSerializer2) spawnAtSameDepth(fromNamespace Namespace) *NamespaceSerializer2 {
    37  	spawned := &NamespaceSerializer2{StringCache: n.StringCache, Variant2: &pb.Variant2{}, logErrors: n.logErrors, currentDepth: n.currentDepth}
    38  	fromNamespace.Serialize(spawned)
    39  	return spawned
    40  }
    41  
    42  func (n *NamespaceSerializer2) dumpOriginalType(originalType string) {
    43  	n.OriginalTypeIndexInCache = n.getStringIndexInCache(originalType)
    44  }
    45  
    46  func (n *NamespaceSerializer2) dumpTypeMaxDepth(variantType uint32, maxDepthInt uint32) {
    47  	n.VariantTypeMaxDepth = uint32((variantType << 1) | maxDepthInt)
    48  }
    49  
    50  func (n *NamespaceSerializer2) dumpType(variantType pb.Variant_Type) {
    51  	maxDepthInt := n.VariantTypeMaxDepth & 1
    52  	n.dumpTypeMaxDepth(uint32(variantType), maxDepthInt)
    53  }
    54  
    55  func (n *NamespaceSerializer2) dumpMaxDepth(maxDepth bool) {
    56  	maxDepthInt := 0
    57  	if maxDepth {
    58  		maxDepthInt = 1
    59  	}
    60  	variantType := n.VariantTypeMaxDepth >> 1
    61  	n.dumpTypeMaxDepth(variantType, uint32(maxDepthInt))
    62  }
    63  
    64  func (n *NamespaceSerializer2) getCurrentDepth() int {
    65  	return n.currentDepth
    66  }
    67  
    68  func (n *NamespaceSerializer2) getStringIndexInCache(s string) uint32 {
    69  	if i, ok := n.StringCache[s]; ok {
    70  		return i
    71  	}
    72  
    73  	n.StringCache[s] = uint32(len(n.StringCache))
    74  	return n.StringCache[s]
    75  }
    76  
    77  func (n *NamespaceSerializer2) dumpUnsupported() {
    78  	n.dumpType(pb.Variant_VARIANT_UKNOWN_OBJECT)
    79  }
    80  
    81  func (n *NamespaceSerializer2) dumpComplex(c complex128) {
    82  	n.dumpType(pb.Variant_VARIANT_COMPLEX)
    83  	n.ComplexValue = &pb.Variant_Complex{Real: real(c), Imaginary: imag(c)}
    84  }
    85  
    86  func (n *NamespaceSerializer2) dumpFloat(f float64) {
    87  	n.dumpType(pb.Variant_VARIANT_DOUBLE)
    88  	n.DoubleValue = f
    89  }
    90  
    91  func (n *NamespaceSerializer2) dumpString(s string, config config.ObjectDumpConfig) {
    92  	if !utf8.ValidString(s) {
    93  		n.dumpBinary([]byte(s), config)
    94  		return
    95  	}
    96  	n.dumpType(pb.Variant_VARIANT_STRING)
    97  	n.OriginalSize = uint32(len(s))
    98  	if len(s) > config.MaxString {
    99  		s = s[:config.MaxString]
   100  	}
   101  	n.BytesIndexInCache = n.getStringIndexInCache(s)
   102  }
   103  
   104  func (n *NamespaceSerializer2) dumpStringLen(stringLen int) {
   105  	n.OriginalSize = uint32(stringLen)
   106  }
   107  
   108  func (n *NamespaceSerializer2) dumpBinary(b []byte, config config.ObjectDumpConfig) {
   109  	n.dumpType(pb.Variant_VARIANT_BINARY)
   110  	n.OriginalSize = uint32(len(b))
   111  	if len(b) > config.MaxString {
   112  		b = b[:config.MaxString]
   113  	}
   114  	n.BytesIndexInCache = n.getStringIndexInCache(string(b))
   115  }
   116  
   117  func (n *NamespaceSerializer2) dumpInt(i int64) {
   118  	n.dumpType(pb.Variant_VARIANT_LONG)
   119  	n.LongValue = i
   120  }
   121  
   122  func (n *NamespaceSerializer2) dumpBool(b bool) {
   123  	n.dumpType(pb.Variant_VARIANT_INT)
   124  	if b {
   125  		n.LongValue = 1
   126  	} else {
   127  		n.LongValue = 0
   128  	}
   129  }
   130  
   131  func (n *NamespaceSerializer2) dumpTime(t time.Time, config config.ObjectDumpConfig) {
   132  	n.dumpType(pb.Variant_VARIANT_TIME)
   133  	n.TimeValue = timestamppb.New(t)
   134  }
   135  
   136  func (n *NamespaceSerializer2) dumpArray(getElem func(i int) (Namespace, bool), arrayLen int, config config.ObjectDumpConfig) {
   137  	n.dumpType(pb.Variant_VARIANT_LIST)
   138  	n.OriginalSize = uint32(arrayLen)
   139  
   140  	if n.getCurrentDepth() >= config.MaxCollectionDepth {
   141  		n.dumpMaxDepth(true)
   142  		return
   143  	}
   144  
   145  	for i := 0; i < arrayLen; i++ {
   146  		if i >= config.MaxWidth {
   147  			return
   148  		}
   149  
   150  		e, ok := getElem(i)
   151  		if !ok {
   152  			break
   153  		}
   154  
   155  		n.CollectionValues = append(n.CollectionValues, n.spawn(e).Variant2)
   156  	}
   157  }
   158  
   159  func (n *NamespaceSerializer2) dumpNamespace(getNamedValue func(i int) (string, Namespace), numOfValues int) {
   160  	n.dumpType(pb.Variant_VARIANT_NAMESPACE)
   161  
   162  	for i := 0; i < numOfValues; i++ {
   163  		name, value := getNamedValue(i)
   164  		n.AttributeNamesInCache = append(n.AttributeNamesInCache, n.getStringIndexInCache(name))
   165  		n.AttributeValues = append(n.AttributeValues, n.spawnAtSameDepth(value).Variant2)
   166  	}
   167  }
   168  
   169  func (n *NamespaceSerializer2) dumpTraceback(getFrame func(i int) (int, string, string), tracebackLen int) {
   170  	n.dumpType(pb.Variant_VARIANT_TRACEBACK)
   171  
   172  	for i := 0; i < tracebackLen; i++ {
   173  		lineno, filename, functionName := getFrame(i)
   174  		n.CodeValues = append(n.CodeValues, &pb.Variant_CodeObject{
   175  			Lineno:               uint32(lineno),
   176  			FilenameIndexInCache: n.getStringIndexInCache(filename),
   177  			NameIndexInCache:     n.getStringIndexInCache(functionName),
   178  			ModuleIndexInCache:   n.getStringIndexInCache(filename),
   179  		})
   180  	}
   181  }
   182  
   183  func (n *NamespaceSerializer2) dumpStruct(getField func(i int) (string, Namespace, bool), numOfFields int, config config.ObjectDumpConfig) {
   184  	n.dumpType(pb.Variant_VARIANT_OBJECT)
   185  
   186  	if n.getCurrentDepth()+1 >= config.MaxDepth {
   187  		n.dumpMaxDepth(true)
   188  		return
   189  	}
   190  
   191  	for i := 0; i < numOfFields; i++ {
   192  		fieldName, fieldValue, ok := getField(i)
   193  		if !ok {
   194  			continue
   195  		}
   196  		n.AttributeNamesInCache = append(n.AttributeNamesInCache, n.getStringIndexInCache(fieldName))
   197  		n.AttributeValues = append(n.AttributeValues, n.spawn(fieldValue).Variant2)
   198  	}
   199  }
   200  
   201  func (n *NamespaceSerializer2) dumpMap(getKeyValue func(i int) (Namespace, Namespace, bool), mapLen int, config config.ObjectDumpConfig) {
   202  	n.dumpType(pb.Variant_VARIANT_MAP)
   203  	n.OriginalSize = uint32(mapLen)
   204  
   205  	if n.getCurrentDepth() >= config.MaxCollectionDepth {
   206  		n.dumpMaxDepth(true)
   207  		return
   208  	}
   209  
   210  	for i := 0; i < mapLen; i++ {
   211  		if i >= config.MaxWidth {
   212  			return
   213  		}
   214  
   215  		key, value, ok := getKeyValue(i)
   216  		if !ok {
   217  			continue
   218  		}
   219  		n.CollectionKeys = append(n.CollectionKeys, n.spawn(key).Variant2)
   220  		n.CollectionValues = append(n.CollectionValues, n.spawn(value).Variant2)
   221  	}
   222  }
   223  
   224  func (n *NamespaceSerializer2) dumpNil() {
   225  	n.dumpType(pb.Variant_VARIANT_NONE)
   226  }
   227  
   228  func (n *NamespaceSerializer2) dumpFunc(functionName string, filename string, lineno int) {
   229  	n.dumpType(pb.Variant_VARIANT_CODE_OBJECT)
   230  	n.CodeValues = append(n.CodeValues, &pb.Variant_CodeObject{
   231  		NameIndexInCache:     n.getStringIndexInCache(functionName),
   232  		ModuleIndexInCache:   n.getStringIndexInCache(filename),
   233  		Lineno:               uint32(lineno),
   234  		FilenameIndexInCache: n.getStringIndexInCache(filename),
   235  	})
   236  }
   237  
   238  func (n *NamespaceSerializer2) dumpChan(value reflect.Value, config config.ObjectDumpConfig) {
   239  	n.dumpType(pb.Variant_VARIANT_LIST)
   240  
   241  	if n.getCurrentDepth() >= config.MaxCollectionDepth {
   242  		n.dumpMaxDepth(true)
   243  		return
   244  	}
   245  
   246  	addr := utils.UnsafePointer(value)
   247  	chanStruct := *(*hchan)(addr)
   248  	elemType := value.Type().Elem()
   249  	bufSize := value.Len() * int(elemType.Size())
   250  
   251  	for i := 0; i < bufSize; i += int(elemType.Size()) {
   252  		if len(n.CollectionValues) >= config.MaxWidth {
   253  			return
   254  		}
   255  
   256  		ptr := unsafe.Pointer(uintptr(chanStruct.buf) + uintptr(i))
   257  		val := reflect.NewAt(elemType, ptr).Elem()
   258  		valVariant := &NamespaceSerializer2{StringCache: n.StringCache, Variant2: &pb.Variant2{}, logErrors: n.logErrors, currentDepth: n.currentDepth + 1}
   259  		dumpValue(valVariant, val, config)
   260  		n.CollectionValues = append(n.CollectionValues, valVariant.Variant2)
   261  	}
   262  }
   263  
   264  func (n *NamespaceSerializer2) dumpRookoutError(r rookoutErrors.RookoutError) {
   265  	n.dumpType(pb.Variant_VARIANT_ERROR)
   266  
   267  	parameters := n.spawn(NewGoObjectNamespace(r.GetArguments()))
   268  	traceback := n.spawn(NewGoObjectNamespace(r.StackFrames()))
   269  	n.ErrorValue = &pb.Error2{
   270  		Message:    r.Error(),
   271  		Type:       r.GetType(),
   272  		Parameters: parameters.Variant2,
   273  		Traceback:  traceback.Variant2,
   274  	}
   275  }
   276  
   277  func (n *NamespaceSerializer2) dumpErrorMessage(msg string) {
   278  	n.dumpType(pb.Variant_VARIANT_ERROR)
   279  	n.ErrorValue = &pb.Error2{
   280  		Message: msg,
   281  	}
   282  }
   283  
   284  func (n *NamespaceSerializer2) dumpEnum(desc string, ordinal int, _ string) {
   285  	n.dumpType(pb.Variant_VARIANT_ENUM)
   286  	n.BytesIndexInCache = n.getStringIndexInCache(desc)
   287  	n.LongValue = int64(ordinal)
   288  }