Merge pull request #506 from paranoiacblack/deprecated-fields

protoc-gen-go: indicate deprecated fields in documentation
diff --git a/jsonpb/jsonpb.go b/jsonpb/jsonpb.go
index 07b313f..ff368f3 100644
--- a/jsonpb/jsonpb.go
+++ b/jsonpb/jsonpb.go
@@ -1134,6 +1134,12 @@
 	for i := 0; i < v.NumField(); i++ {
 		field := v.Field(i)
 		sfield := v.Type().Field(i)
+
+		if sfield.PkgPath != "" {
+			// blank PkgPath means the field is exported; skip if not exported
+			continue
+		}
+
 		if strings.HasPrefix(sfield.Name, "XXX_") {
 			continue
 		}
@@ -1156,8 +1162,12 @@
 			sfield = v.Type().Field(0)
 		}
 
+		protoTag := sfield.Tag.Get("protobuf")
+		if protoTag == "" {
+			continue
+		}
 		var prop proto.Properties
-		prop.Init(sfield.Type, sfield.Name, sfield.Tag.Get("protobuf"), &sfield)
+		prop.Init(sfield.Type, sfield.Name, protoTag, &sfield)
 
 		switch field.Kind() {
 		case reflect.Map:
diff --git a/jsonpb/jsonpb_test.go b/jsonpb/jsonpb_test.go
index d98f586..c9934d9 100644
--- a/jsonpb/jsonpb_test.go
+++ b/jsonpb/jsonpb_test.go
@@ -533,6 +533,19 @@
 	}
 }
 
+func TestMarshalWithCustomValidation(t *testing.T) {
+	msg := dynamicMessage{rawJson: `{ "foo": "bar", "baz": [0, 1, 2, 3] }`, dummy: &dynamicMessage{}}
+
+	js, err := new(Marshaler).MarshalToString(&msg)
+	if err != nil {
+		t.Errorf("an unexpected error occurred when marshalling to json: %v", err)
+	}
+	err = Unmarshal(strings.NewReader(js), &msg)
+	if err != nil {
+		t.Errorf("an unexpected error occurred when unmarshalling from json: %v", err)
+	}
+}
+
 // Test marshaling message containing unset required fields should produce error.
 func TestMarshalUnsetRequiredFields(t *testing.T) {
 	msgExt := &pb.Real{}
@@ -1004,6 +1017,10 @@
 // It provides implementations of JSONPBMarshaler and JSONPBUnmarshaler for JSON support.
 type dynamicMessage struct {
 	rawJson string `protobuf:"bytes,1,opt,name=rawJson"`
+
+	// an unexported nested message is present just to ensure that it
+	// won't result in a panic (see issue #509)
+	dummy *dynamicMessage `protobuf:"bytes,2,opt,name=dummy"`
 }
 
 func (m *dynamicMessage) Reset() {
diff --git a/proto/pointer_reflect.go b/proto/pointer_reflect.go
index dea727c..68798c9 100644
--- a/proto/pointer_reflect.go
+++ b/proto/pointer_reflect.go
@@ -29,7 +29,7 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// +build appengine js
+// +build purego appengine js
 
 // This file contains an implementation of proto field accesses using package reflect.
 // It is slower than the code in pointer_unsafe.go but it avoids package unsafe and can
diff --git a/proto/pointer_unsafe.go b/proto/pointer_unsafe.go
index 4197ae3..ce7089b 100644
--- a/proto/pointer_unsafe.go
+++ b/proto/pointer_unsafe.go
@@ -29,7 +29,7 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// +build !appengine,!js
+// +build !purego,!appengine,!js
 
 // This file contains the implementation of the proto field accesses using package unsafe.