Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set field of a nested message in protocol buffers?

I have a proto file that looks like this:

message terminal_data
{
    required int32 type = 1;              //1-->trade 2-->order

    message trade_data
    {
        optional string client_id =   1;
        optional string strat_id =    2;
        optional string symbol_name = 3;
        optional int64  trade_id =    4;
        optional string expiry =      5;
        optional int64  quantity =    6;
        optional string time =        7;

    }

    message order_data
    {
        optional string client_id =    1;
        optional string strat_id =     2;
        optional string symbol_name =  3;
        optional int64  order_id =     4;
        optional string side =         5;
        optional int64  quantity =     6;
        optional string time =         7;
    }

}

Now to set data, I am doing this:

 tData.trade_data.mutable_client_id();

It complains:

:

 error: invalid use of 'data_model::terminal_data::trade_data'
     tData.trade_data.mutable_client_id();
           ^

What is the correct way to set the nested message ?

Here is the generated code:

class terminal_data : public ::google::protobuf::Message {
 public:
  terminal_data();
  virtual ~terminal_data();

  terminal_data(const terminal_data& from);

  inline terminal_data& operator=(const terminal_data& from) {
    CopyFrom(from);
    return *this;
  }

  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    return _unknown_fields_;
  }

  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return &_unknown_fields_;
  }

  static const ::google::protobuf::Descriptor* descriptor();
  static const terminal_data& default_instance();

  void Swap(terminal_data* other);

  // implements Message ----------------------------------------------

  terminal_data* New() const;
  void CopyFrom(const ::google::protobuf::Message& from);
  void MergeFrom(const ::google::protobuf::Message& from);
  void CopyFrom(const terminal_data& from);
  void MergeFrom(const terminal_data& from);
  void Clear();
  bool IsInitialized() const;

  int ByteSize() const;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input);
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const;
  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
  int GetCachedSize() const { return _cached_size_; }
  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const;
  public:

  ::google::protobuf::Metadata GetMetadata() const;

  // nested types ----------------------------------------------------

  typedef terminal_data_trade_data trade_data;
  typedef terminal_data_order_data order_data;

  // accessors -------------------------------------------------------

  // required int32 type = 1;
  inline bool has_type() const;
  inline void clear_type();
  static const int kTypeFieldNumber = 1;
  inline ::google::protobuf::int32 type() const;
  inline void set_type(::google::protobuf::int32 value);

  // @@protoc_insertion_point(class_scope:data_model.terminal_data)
 private:
  inline void set_has_type();
  inline void clear_has_type();

  ::google::protobuf::UnknownFieldSet _unknown_fields_;

  ::google::protobuf::int32 type_;

  mutable int _cached_size_;
  ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32];

  friend void  protobuf_AddDesc_data_5fmodel_2eproto();
  friend void protobuf_AssignDesc_data_5fmodel_2eproto();
  friend void protobuf_ShutdownFile_data_5fmodel_2eproto();

  void InitAsDefaultInstance();
  static terminal_data* default_instance_;
};
like image 308
Chani Avatar asked Aug 16 '14 08:08

Chani


People also ask

How do you deprecate a field in Protobuf?

Protobuf has an option for marking a “field” as deprecated. optional int32 old_field = 6 [deprecated=true]; Full snipped from their documentation: deprecated (field option): If set to true , indicates that the field is deprecated and should not be used by new code.

Are Protobuf fields optional?

As of Google Protobuf version 3.15, optional fields are reintroduced in proto3. Embedded Proto supports optional fields as of version 2.3. 0. This feature allows you to track if a field has been set.

What is the difference between proto2 and Proto3?

Proto3 is the latest version of Protocol Buffers and includes the following changes from proto2: Field presence, also known as hasField , is removed by default for primitive fields. An unset primitive field has a language-defined default value.


1 Answers

The proto definition of terminal_data defines a nested message trade_data - but it doesn't actually define a field whose type is that message. terminal_data only has one field, type. Add something like

optional trade_data trade = 2;
optional order_data order = 3;

It's exactly like in C++, you can write

class Outer {
  class Inner {};
};

Just because you've defined a nested class, doesn't mean the outer class magically acquires a member whose type is that nested class.

like image 194
Igor Tandetnik Avatar answered Oct 11 '22 04:10

Igor Tandetnik