Protocol Buffers: How to make .proto file for enum?

13,806

Solution 1

Based on the accepted answer and some further investigation here a full working example.

assume following files in the current directory

PaxTypeEnum.proto
TestProtobufEnum.java
// https://github.com/google/protobuf/releases
protoc-3.1.0-linux-x86_64.zip
// https://mvnrepository.com/artifact/com.google.protobuf/protobuf-java
protobuf-java-3.1.0.jar 

PaxTypeEnum.proto

syntax = "proto2";

import "google/protobuf/descriptor.proto";

message EnumProto {
  extend google.protobuf.EnumValueOptions {
    optional string name = 50000;
    optional string singleCharCode = 50001;
  }

  enum PaxType {
    ADULT = 0 [(name) = "ADT", (singleCharCode) = 'A'];
    CHILD = 1 [(name) = "CNN", (singleCharCode) = 'C'];
    INFANT = 2 [(name) = "IFT", (singleCharCode) = 'I'];
  }
}

TestProtobufEnum.java

import com.google.protobuf.DescriptorProtos;
import com.google.protobuf.Descriptors;
import java.util.Map;
import java.util.Set;

class TestProtobufEnum {
    public static void main(String[] args) {
        PaxTypeEnum.EnumProto.PaxType CHILD =.
            PaxTypeEnum.EnumProto.PaxType.CHILD;

        System.out.println("get fields dynamically for PaxType.CHILD");
        Set<Map.Entry<Descriptors.FieldDescriptor, Object>> allFields =.
            CHILD.getValueDescriptor().getOptions().getAllFields().entrySet();
        for (Map.Entry<Descriptors.FieldDescriptor, Object> entry : allFields){
            System.out.printf("field: descriptor: %-14s  value: %s%n",
                    entry.getKey().getName(),
                    entry.getValue()
            );
        }

        System.out.println("get fields statically");
        PaxTypeEnum.EnumProto.PaxType[] paxTypes =.
                PaxTypeEnum.EnumProto.PaxType.values();
        for (PaxTypeEnum.EnumProto.PaxType value : paxTypes) {
            DescriptorProtos.EnumValueOptions options =.
                    value.getValueDescriptor().getOptions();
            System.out.printf("PaxType: %-6s  name: %s  singleCharCode: %s%n",
                    value.toString(),
                    options.getExtension(PaxTypeEnum.EnumProto.name),
                    options.getExtension(PaxTypeEnum.EnumProto.singleCharCode)
            );
        }

    }
}
  1. unzip protoc-3.1.0-linux-x86_64.zip in current directory
  2. set environment variables

    PROTO_HOME=$(pwd)
    PATH=${PROTO_HOME}/bin:${PATH}
    
  3. generate the Java source from the *.proto file

    protoc PaxTypeEnum.proto --java_out=. --proto_path=${PROTO_HOME}/include:.
    
  4. compile the Java demo

    javac -cp .:protobuf-java-3.1.0.jar TestProtobufEnum.java
    
  5. run the Java demo

    java -cp .:protobuf-java-3.1.0.jar TestProtobufEnum
    

output

get fields dynamically for PaxType.CHILD
field: descriptor: name            value: CNN
field: descriptor: singleCharCode  value: C

get fields statically
PaxType: ADULT   name: ADT  singleCharCode: A
PaxType: CHILD   name: CNN  singleCharCode: C
PaxType: INFANT  name: IFT  singleCharCode: I

Solution 2

There is not any recommended way to represent java enum classes. But you can follow something like below.

import "google/protobuf/descriptor.proto";

extend google.protobuf.EnumValueOptions {
  optional string type= 51234;
  optional string code= 51235;
}

enum PaxType {
  ADULT = 0 [(type) = "ADT", (code) = 'A'];
  CHILD = 1 [(type) = "CNN", (code) = 'C'];
  INFANT = 2 [(type) = "IFT", (code) = 'I']
}

The annotation is accessed through the EnumValueDescriptor interface.

Share:
13,806
Vivek Sinha
Author by

Vivek Sinha

In order to understand recursion, one must first understand recursion.

Updated on June 05, 2022

Comments

  • Vivek Sinha
    Vivek Sinha almost 2 years

    My enum in java looks like this(mentioned below). What it would be in .proto? Not able to figure out how to take care of constructor and Getter methods for the variables (type and code).

    public enum PaxType {
        ADULT("ADT", 'A'),
        CHILD("CNN", 'C'),
        INFANT("IFT", 'I');
    
        private String type;
        private char   code;
    
        PaxType(String type, char code) {
            this.type = type;
            this.code = code;
        }
    
        public String getType() {
            return type;
        }
    
        public char getCode() {
            return code;
        }
    }
    
  • skal
    skal over 3 years
    can you elaborate on what the meaning of the numbers is 50000 and 50001? Trying to understand those numbers, thanks
  • skal
    skal over 3 years
    can you elaborate on what the meaning of the numbers is 51234 and 51235? Trying to understand those numbers, thanks
  • SubOptimal
    SubOptimal over 3 years
    @skal The numbers are the field numbers which uniquely identify the field in the encoding. For more information have a look into the documentation developers.google.com/protocol-buffers/docs/….