Protocol Buffers 3.0 and JSON, just what does that mean.

5,789 views
Skip to first unread message

Carl

unread,
Jun 13, 2016, 12:47:38 PM6/13/16
to Protocol Buffers
Greetings:

     As someone who is fairly familiar with PB 2.0, I have used it for 2+ years. I feel comfortable standard C++ API of has_*. set_* and the parsing and serialization APIs.

     But now as I am moving to PB 3.0 I keep hearing of JSON as a possible serialization format. But how?

      Is there an example of how a C++ app can read/write a PB to JSON. I already have a include file (.h) generated via protoc (ver 3) and don't see a published UI.

Thanks
Carl

Chad Beaulac

unread,
Jun 15, 2016, 11:02:02 AM6/15/16
to Protocol Buffers
Attached is a GTest that serializes to JSON, uses the google.protobuf.Timestamp type and sets an Any field.
Example of attached:
syntax = "proto3";

import "google/protobuf/any.proto";
import "google/protobuf/timestamp.proto";

package movie.pbuf;


// This message is a one-to-one mapping to the Movie Collection in our MongoDB
message Movie {
  google.protobuf.Timestamp start_time = 1;
  string movie_name = 2;
  // TODO action flag
  // TODO add more here
}

message CommandControlMsg {
  string message = 1;
  google.protobuf.Any command = 2;
}


Here's a test snippet
/**
 * Serialize a protobuf message to JSON and parse back again.
 */
TEST_F(BasicProtoGtest, SerializeToJsonAndBackAgain) {
  // Movie PBUF message
  Movie startMovie;

  struct timeval tv;
  gettimeofday(&tv, NULL);

  ::google::protobuf::Timestamp* timestamp = new ::google::protobuf::Timestamp();
  timestamp->set_seconds(tv.tv_sec);
  timestamp->set_nanos(tv.tv_usec * 1000);
  
  startMovie.set_allocated_start_time(timestamp);
  startMovie.set_movie_name("my happy movie");
  
  std::string serialized = startMovie.SerializeAsString();
  std::string json_string;
  
  // Create a TypeResolver used to resolve protobuf message types
  google::protobuf::util::JsonOptions options;
  options.always_print_primitive_fields = true;
  std::unique_ptr<google::protobuf::util::TypeResolver> resolver(google::protobuf::util::NewTypeResolverForDescriptorPool(
    "type.googleapis.com", google::protobuf::DescriptorPool::generated_pool())); 
  
  // Assert we can find the Movie type in the resolver
  Type type;
  ASSERT_TRUE(resolver->ResolveMessageType(
  
  auto status = google::protobuf::util::BinaryToJsonString(resolver.get(), "type.googleapis.com/movie.pbuf.Movie", serialized, &json_string, options);
//   std::cout << "~~~~~~~ bin str\n" << serialized << std::endl;
   std::cout << "*******\n" << json_string << std::endl;
  
  // Turn JSON into serialized protobuf message
  std::string movieBin;
  google::protobuf::util::JsonToBinaryString(resolver.get(), "type.googleapis.com/movie.pbuf.Movie", json_string, &movieBin);  
  
  Movie startMovie2;
  startMovie2.ParseFromString(movieBin);
  
  EXPECT_EQ(startMovie.movie_name(), startMovie2.movie_name());
  EXPECT_EQ(startMovie.start_time(), startMovie2.start_time());  
}

Build the project with cmake using standard "out of source" build:
cd project_dir
mkdir build
cd build
cmake ..
make
ctest


This was done on Fedora Core 23
basic_proto_gtest.cpp
basic_proto_gtest.h
CMakeLists.txt
gtestProtobufMain.cpp
movie.proto

Carl Slater

unread,
Jun 15, 2016, 12:07:10 PM6/15/16
to Chad Beaulac, Protocol Buffers
Chad 

    You nailed it.... thank you thank you.

    Where should I have seen this in the doc? Seems the class TypeResolver  was the missing link, but this is my first exposure to it.

    Again thanks.

Regards
Carl


--
You received this message because you are subscribed to a topic in the Google Groups "Protocol Buffers" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/protobuf/ecxdP_mN8OI/unsubscribe.
To unsubscribe from this group and all its topics, send an email to protobuf+u...@googlegroups.com.
To post to this group, send email to prot...@googlegroups.com.
Visit this group at https://groups.google.com/group/protobuf.
For more options, visit https://groups.google.com/d/optout.

Chad Beaulac

unread,
Jun 15, 2016, 12:15:02 PM6/15/16
to Protocol Buffers, cabe...@gmail.com
Thanks Carl
I don't know where this should/could be in the docs. I didn't find documentation for it either. I searched the C++ source for unit tests and read the unit tests.
json_util_test.cc is in this directory.

protobuf-3.0.0-beta-3/src/google/protobuf/util


-Chad
Reply all
Reply to author
Forward
0 new messages