go.uber.org/cadence@v1.2.9/internal/encoded.go (about)

     1  // Copyright (c) 2017 Uber Technologies, Inc.
     2  //
     3  // Permission is hereby granted, free of charge, to any person obtaining a copy
     4  // of this software and associated documentation files (the "Software"), to deal
     5  // in the Software without restriction, including without limitation the rights
     6  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     7  // copies of the Software, and to permit persons to whom the Software is
     8  // furnished to do so, subject to the following conditions:
     9  //
    10  // The above copyright notice and this permission notice shall be included in
    11  // all copies or substantial portions of the Software.
    12  //
    13  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    14  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    15  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    16  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    17  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    18  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    19  // THE SOFTWARE.
    20  
    21  package internal
    22  
    23  import (
    24  	"reflect"
    25  
    26  	"go.uber.org/cadence/internal/common"
    27  	"go.uber.org/cadence/internal/common/util"
    28  )
    29  
    30  type (
    31  	// Value is used to encapsulate/extract encoded value from workflow/activity.
    32  	Value interface {
    33  		// HasValue return whether there is value encoded.
    34  		HasValue() bool
    35  		// Get extract the encoded value into strong typed value pointer.
    36  		Get(valuePtr interface{}) error
    37  	}
    38  
    39  	// Values is used to encapsulate/extract encoded one or more values from workflow/activity.
    40  	Values interface {
    41  		// HasValues return whether there are values encoded.
    42  		HasValues() bool
    43  		// Get extract the encoded values into strong typed value pointers.
    44  		Get(valuePtr ...interface{}) error
    45  	}
    46  
    47  	// DataConverter is used by the framework to serialize/deserialize input and output of activity/workflow
    48  	// that need to be sent over the wire.
    49  	// To encode/decode workflow arguments, one should set DataConverter in two places:
    50  	//   1. Workflow worker, through worker.Options
    51  	//   2. Client, through client.Options
    52  	// To encode/decode Activity/ChildWorkflow arguments, one should set DataConverter in two places:
    53  	//   1. Inside workflow code, use workflow.WithDataConverter to create new Context,
    54  	// and pass that context to ExecuteActivity/ExecuteChildWorkflow calls.
    55  	// Cadence support using different DataConverters for different activity/childWorkflow in same workflow.
    56  	//   2. Activity/Workflow worker that run these activity/childWorkflow, through worker.Options.
    57  	DataConverter interface {
    58  		// ToData implements conversion of a list of values.
    59  		ToData(value ...interface{}) ([]byte, error)
    60  		// FromData implements conversion of an array of values of different types.
    61  		// Useful for deserializing arguments of function invocations.
    62  		FromData(input []byte, valuePtr ...interface{}) error
    63  	}
    64  
    65  	// defaultDataConverter uses thrift encoder/decoder when possible, for everything else use json.
    66  	defaultDataConverter struct{}
    67  )
    68  
    69  var defaultJSONDataConverter = &defaultDataConverter{}
    70  
    71  // DefaultDataConverter is default data converter used by Cadence worker
    72  var DefaultDataConverter = getDefaultDataConverter()
    73  
    74  // getDefaultDataConverter return default data converter used by Cadence worker
    75  func getDefaultDataConverter() DataConverter {
    76  	return defaultJSONDataConverter
    77  }
    78  
    79  func (dc *defaultDataConverter) ToData(r ...interface{}) ([]byte, error) {
    80  	if len(r) == 1 && util.IsTypeByteSlice(reflect.TypeOf(r[0])) {
    81  		return r[0].([]byte), nil
    82  	}
    83  
    84  	var encoder encoding
    85  	if common.IsUseThriftEncoding(r) {
    86  		encoder = &thriftEncoding{}
    87  	} else {
    88  		encoder = &jsonEncoding{}
    89  	}
    90  
    91  	data, err := encoder.Marshal(r)
    92  	if err != nil {
    93  		return nil, err
    94  	}
    95  	return data, nil
    96  }
    97  
    98  func (dc *defaultDataConverter) FromData(data []byte, to ...interface{}) error {
    99  	if len(to) == 1 && util.IsTypeByteSlice(reflect.TypeOf(to[0])) {
   100  		reflect.ValueOf(to[0]).Elem().SetBytes(data)
   101  		return nil
   102  	}
   103  
   104  	var encoder encoding
   105  	if common.IsUseThriftDecoding(to) {
   106  		encoder = &thriftEncoding{}
   107  	} else {
   108  		encoder = &jsonEncoding{}
   109  	}
   110  
   111  	return encoder.Unmarshal(data, to)
   112  }