
- Protobuf Tutorial
- Protobuf - Home
- Protobuf - Introduction
- Protobuf - Basic App
- Protobuf - Constructs
- Protobuf - Class/Member
- Protobuf - Strings
- Protobuf - Numbers
- Protobuf - Boolean
- Protobuf - Enum
- Protobuf - List/Repeated
- Protobuf - Map
- Protobuf - Nested Class
- Protobuf - Optionality & Defaults
- Protobuf - Language Independence
- Protobuf - Compound Data Types
- Protobuf - Command Line Usage
- Protobuf - Rules to Update Definition
- Protobuf - Integration with Kafka
- Protobuf - In Other Languages
- Protobuf Useful Resources
- Protobuf - Quick Guide
- Protobuf - Useful Resources
- Protobuf - Discussion
Protobuf - Language Independence
Till now, we have been using Java to serialize and deserialize the Movie Theater data. However, one of the key features that Google Protobuf provides is "language independence". In this chapter, we will see how to serialize using Java and deserialize using Python.
Sample Proto file syntax = "proto3"; package theater; option java_package = "com.tutorialspoint.theater"; message Theater { string name = 1; string address = 2; int32 total_capcity = 3; int64 mobile = 4; float base_ticket_price = 5; bool drive_in = 6; enum PAYMENT_SYSTEM { CASH = 0; CREDIT_CARD = 1; DEBIT_CARD = 2; APP = 3; } PAYMENT_SYSTEM payment = 7; repeated string snacks = 8; map<string, int32> movieTicketPrice = 9; TheaterOwner owner = 10; } message TheaterOwner{ string name = 1; string address = 2; }
Serialization using Java
To use Protobuf with Java, we will now have to use protoc binary to create the required classes from this ".proto" file. Let us see how to do that −
protoc --java_out=java/src/main/java proto_files\theater.proto
The above command should create the required files and now we can use it in our Java code. First, we will create a writer to write the theater information −
package com.tutorialspoint.theater; import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import com.tutorialspoint.theater.TheaterOuterClass.Theater; import com.tutorialspoint.theater.TheaterOuterClass.TheaterOwner; import com.tutorialspoint.theater.TheaterOuterClass.Theater.PAYMENT_SYSTEM; public class TheaterWriterComplete{ public static void main(String[] args) throws IOException { TheaterOwner owner = TheaterOwner.newBuilder() .setName("Anthony Gonsalves") .setAddress("513, St Paul Street, West Coast, California") .build(); List<String> snacks = new ArrayList<>(); snacks.add("Popcorn"); snacks.add("Coke"); snacks.add("Chips"); snacks.add("Soda"); Map<String, Integer> ticketPrice = new HashMap<>(); ticketPrice.put("Avengers Endgame", 700); ticketPrice.put("Captain America", 200); ticketPrice.put("Wonder Woman 1984", 400); Theater theater = Theater.newBuilder() .setName("Silver Screener") .setAddress("212, Maple Street, LA, California") .setDriveIn(true) .setTotalCapcity(320) .setMobile(98234567189L) .setBaseTicketPrice(22.45f) .setPayment(PAYMENT_SYSTEM.CREDIT_CARD) .putAllMovieTicketPrice(ticketPrice) .addAllSnacks(snacks) .setOwner(owner) .build(); String filename = "theater_protobuf_output"; System.out.println("Saving theater information to file: " + filename); try(FileOutputStream output = new FileOutputStream(filename)){ theater.writeTo(output); } System.out.println("Saved theater information with following data to disk: \n" + theater); } }
Now, post compilation, let us execute the writer first −
> java -cp .\target\protobuf-tutorial-1.0.jar com.tutorialspoint.theater.TheaterWriter Saving theater information to file: theater_protobuf_output Saved theater information with following data to disk: name: "Silver Screener" address: "212, Maple Street, LA, California" total_capcity: 320 mobile: 98234567189 base_ticket_price: 22.45 drive_in: true payment: CREDIT_CARD snacks: "Popcorn" snacks: "Coke" snacks: "Chips" snacks: "Soda" movieTicketPrice { key: "Avengers Endgame" value: 700 } movieTicketPrice { key: "Captain America" value: 200 } movieTicketPrice { key: "Wonder Woman 1984" value: 400 } owner { name: "Anthony Gonsalves" address: "513, St Paul Street, West Coast, California" }
Deserialization using Python
Next, we will have a reader to read the theater information −
package com.tutorialspoint.theater; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.util.Map; import com.google.protobuf.DescriptorProtos.FileDescriptorProto; import com.google.protobuf.Descriptors.FieldDescriptor; import com.google.protobuf.Descriptors.FileDescriptor; import com.tutorialspoint.greeting.Greeting.Greet; import com.tutorialspoint.theater.TheaterOuterClass.Theater; import com.tutorialspoint.theater.TheaterOuterClass.Theater.Builder; public class TheaterReaderExplicit { public static void main(String[] args) throws IOException { Builder theaterBuilder = Theater.newBuilder(); String filename = "theater_protobuf_output"; System.out.println("Reading from file " + filename); try(FileInputStream input = new FileInputStream(filename)) { Theater theater = theaterBuilder.mergeFrom(input).build(); System.out.println( "Name:" + theater.getName() + "\n" + "Address:" + theater.getAddress() + "\n" + "Drive_In:" + theater.getDriveIn() + "\n" + "Total Capacity:" + theater.getTotalCapcity() + "\n" + "Base Ticket Prices: " + theater.getBaseTicketPrice() + "\n" + "Owner: " + theater.getOwner() + "\n" + "Snacks: " + theater.getSnacksList() + "\n" + "Payment: " + theater.getPayment() ); //Map<FieldDescriptor, Object> f = theater.getAllFields(); System.out.println("List of fields explicitly specified: " + theater.getAllFields()); } } }
Output
Saving theater information to file: theater_protobuf_output Saved theater information with following data to disk: name: "SilverScreen"
To use Protobuf with Python, we will now have to use protoc binary to create the required classes from this ".proto" file. Let us see how to do that −
protoc --python_out=python proto_files\theater.proto
The above command should create the required files and now we can use it in our Python code. Now, let us write a Python reader −
from proto_files import theater_pb2 from pathlib import Path path = Path() filename = str(path.parent.absolute().parent.joinpath("java").joinpath("theater_protobuf_output")); print("Reading from file: " + filename) theater = theater_pb2.Theater() f = open(filename, "rb") theater.ParseFromString(f.read()) f.close() print("Read greeting from disk: \n" + str(theater))
We read the theater_protobuf_output file which is generated in the Java directory. Now, let us execute the code −
python theaterReader.py Reading from file: google-protobuf\java\theater_protobuf_output Read greeting from disk: name: "Silver Screener" address: "212, Maple Street, LA, California" total_capcity: 320 mobile: 98234567189 base_ticket_price: 22.45 drive_in: true payment: CREDIT_CARD snacks: "Popcorn" snacks: "Coke" snacks: "Chips" snacks: "Soda" movieTicketPrice { key: "Avengers Endgame" value: 700 } movieTicketPrice { key: "Captain America" value: 200 } movieTicketPrice { key: "Wonder Woman 1984" value: 400 } owner { name: "Anthony Gonsalves" address: "513, St Paul Street, West Coast, California" }
So, as we see, all the values which were written by the Java client were correctly deserialized and read by our Python client which effectively means Protobuf is language independent.