2013-12-17 2 views
4

내가 자바에서는 다음과 같은 내용중첩 된 프로토콜 버퍼가

Message Foo { 
    Message Bar { 
     optional int32 a = 1; 
     optional int32 b = 2; 
    } 
    optional Bar bar = 1; 
} 

와 .proto 파일에 메시지를 말해봐, "bar.a을"단지 문자열을 사용하여 필드 설정 어쨌든 있나요? 이상 적으로 나는 아래와 같은 메소드를 작성하고 싶습니다.

public Foo.Builder apply(Foo.Builder builder, String fieldPath, Object value) { 
    // fieldPath == "bar.a" 
    // This doesn't work 
    FieldDescriptor fd = builder.getDefaultInstanceForType().findFieldByName(fieldPath); 
    builder = builder.setField(fd, value); 
} 

그러나 이렇게하면 IllegalArgumentException이 발생합니다.

누구나 일반적인 방법으로이 작업을 수행하는 방법을 알고 있습니까?

나는 또한 FieldPath에는이 구분 (".")와 참조 기본 메시지를 포함하지 않는 경우뿐만 아니라

public Object getValue(Foo message, String fieldPath) { 
    // This doesn't work 
    FieldDescriptor fd = message.getDefaultInstanceForType().findFieldByName(fieldPath); 
    return message.getField(fieldPath); 
} 

참고로 다른 길을 가고,이 잘 작동해야하지만이 아닌 중첩 된 메시지.

+1

'foo.a'가 맞습니까? 나는 Foo의 구조에 따라'foo.bar.a'가되어야한다고 생각한다. – Muel

+0

정확하며 질문이 업데이트되었습니다. – Jon

답변

4

'.'에서 필드 경로를 분할해야합니다. 검색의 체인을 수행합니다 (예 :

Message subMessage = 
    (Message)message.getField(
     message.getDescriptorForType().findFieldByName("bar")); 
return subMessage.getField(
    subMessage.getDescriptorForType().findFieldByName("a")); 

또는 쓰기 :

FieldDescriptor desc = message.getDescriptorForType().findFieldByName("bar"); 
Message.Builder subBuilder = (Message.Builder)builder.getFieldBuilder(desc); 
subBuilder.setField(
    subMessage.getDescriptorForType().findFieldByName("a"), value); 
builder.setField(desc, subBuilder.build()); 

당신은 물론 문자열을 나누고 각각을 하나의 호출로 모든 조회를 수행하는 라이브러리를 쓰기 (및 적절한 검사 오류를 할) 수있다.

관련 문제