Skip to content

protoc-gen-go: generate Setters for oneof fields #283

Open
@thakkarparth007

Description

@thakkarparth007

The library provides only Getters for oneof fields. Because of this, setting oneof fields is painful. And this gets especially painful when the oneof fields are themselves proto messages. For example:

message RequestWrapper {
    string request_id = 1;
    string session_id = 2;

    oneof request {
		actions.BuyStocksFromExchangeRequest buy_stocks_from_exchange_request = 3;
		actions.CancelAskOrderRequest cancel_ask_order_request = 4;
		actions.CancelBidOrderRequest cancel_bid_order_request = 5;
                . . .
    }
}

message ResponseWrapper {
    string request_id = 1;

    oneof response {
		actions.BuyStocksFromExchangeResponse buy_stocks_from_exchange_response = 3;
		actions.CancelAskOrderResponse cancel_ask_order_response = 4;
		actions.CancelBidOrderResponse cancel_bid_order_response = 5;
                . . .
    }
}

message DalalMessage {
    oneof message_type {
        RequestWrapper request_wrapper = 1;
        ResponseWrapper response_wrapper = 2;
        DataStreamUpdateWrapper data_stream_update_wrapper = 3;
    }
}

Here, The Response messages themselves have oneof fields. Creating a DalalMessage type, then, has to be done in this manner:

dm := &socketapi_proto.DalalMessage{}
dm.MessageType = &socketapi_proto.DalalMessage_ResponseWrapper{
	ResponseWrapper: &socketapi_proto.ResponseWrapper{
		Response: &socketapi_proto.ResponseWrapper_BuyStocksFromExchangeResponse{
			BuyStocksFromExchangeResponse: response.(*actions_proto.BuyStocksFromExchangeResponse),
		},
	},
}

This is clearly painful. Instead, if setter methods are provided, the same code would be much shorter and readable:

rw := &socketapi_proto.DalalMessage_ResponseWrapper{}
rw.SetResponse(response.(*actions_proto.BuyStocksFromExchangeResponse))

dm := &socketapi_proto.DalalMessage{}
dm.SetResponseWrapper(rw)

Of course, this can be shortened further if protobuf does not wrap the fields inside a oneof field, but I assume that will break a lot of people's code. I also don't know the side effects of not wrapping oneof fields.

Even if the oneof fields stay wrapped, I believe that providing Setters will neither break anyone's code, nor will cause any side effects.

Sample output after adding a Setter:

// Generated already
func (m *DalalMessage) GetRequestWrapper() *RequestWrapper {
	if x, ok := m.GetMessageType().(*DalalMessage_RequestWrapper); ok {
		return x.RequestWrapper
	}
	return nil
}

// Generated as per this proposal
func (m *DalalMessage) SetRequestWrapper(rw *RequestWrapper) {
	m.MessageType = &DalalMessage_RequestWrapper{
		RequestWrapper: rw,
	}
}

I'm sure there are others facing this issue. (#205).

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions